Часткове оновлення сутності у Фабриці даних
- 1. Загальний опис
- 2. Використання та налаштування у бізнес-процесі
- 2.1. Створення пулу для бізнес-процесу
- 2.2. Моделювання стартової форми
- 2.3. Моделювання форми для підпису даних КЕП
- 2.4. Моделювання задачі скриптування "Підготовка даних до запису (transient var)"
- 2.5. Моделювання Call Activity для підпису даних системним ключем
- 2.6. Моделювання сервісної задачі для створення сутності в базі даних
- 2.7. Моделювання сервісної задачі для пошуку сутності в базі даних
- 2.8. Моделювання задачі скриптування для отримання даних учня
- 2.9. Моделювання користувацької форми для редагування даних
- 2.10. Моделювання користувацької форми для підпису змінених даних КЕП
- 2.11. Моделювання задачі скриптування для формування об’єкта зі зміненими даними
- 2.12. Моделювання Call Activity для підпису оновлених даних системним ключем
- 2.13. Моделювання сервісної задачі для часткового оновлення сутності відповідно до внесених змін
- 2.14. Моделювання події завершення процесу
- 3. Імплементація на рівні API
- 4. Імплементація на рівні моделі даних
1. Загальний опис
Для всіх таблиць у Фабриці даних, з якими взаємодіють сервіси, на Платформі використовується 4 основних HTTP-методи: POST, GET, PUT та DELETE.
Для оновлення сутності у Фабриці даних використовується метод PUT та відповідний імплементований делегат Update entity in data factory.
При використанні PUT, у тілі запита необхідно вказувати значення усіх полів таблиці, навіть тих, які оновлення не потребують. Така поведінка передбачена для методу PUT за замовчуванням.
Наприклад, маємо таблицю, яка містить 5 полів: Ім’я, Прізвище, По батькові, Дата народження, Місце роботи. Нам потрібно оновити лише 1-ше поле (Ім’я) з 5-ти.
При використанні метода PUT, необхідно буде встановити значення для кожного з 5-ти полів об’єкта.
Інакше всі незаповнені поля автозаповняться як NULL.
Функціональність часткового оновлення сутності (partialUpdate) розв’язує цю проблему. Часткове оновлення на рівні API використовує HTTP-метод PATCH. Цей метод ігнорує всі незаповнені поля, не зазначені у тілі запита. Він опрацьовує лише ті параметри, які потребують оновлення.
Відповідно на рівні API реалізовано окремий ендпоінт для роботи за методом PATCH, який дозволяє частково оновити сутність у базі даних (див. Імплементація на рівні API).
Для взаємодії з API та можливості надсилати бізнес-дані до БД, на рівні бізнес-процесів розроблено типове розширення — делегат ${dataFactoryConnectorPartialUpdateDelegate}, для якого імплементовано однойменний шаблон Update entity in data factory partially, представлений у вигляді JSON-файлу dataFactoryConnectorPartialUpdateDelegate.json.
Делегат потрібний для того, щоб оновлювати значення конкретних параметрів у таблиці БД.
2. Використання та налаштування у бізнес-процесі
Розглянемо приклад моделювання бізнес-процесу із застосуванням делегата для часткового (вибіркового) оновлення параметрів сутності.
Метою цього бізнес-процесу є створення сутності у Фабриці даних, подальший пошук створеної сутності за ID та оновлення лише певних параметрів цієї сутності, тобто її часткове оновлення.
2.1. Створення пулу для бізнес-процесу
Найперше, необхідно змоделювати пул для бізнес-процесу. Для цього виконайте такі налаштування:
-
Відкрийте додаток Camunda Modeler та створіть нову діаграму BPMN. Для цього у лівому верхньому куті натисніть меню File → New File → BPMN Diagram.

-
На панелі інструментів зліва знайдіть елемент Create pool/Participant та перетягніть його до області моделювання.

-
Заповніть наступні поля відповідними значеннями:
-
У полі
Participant Nameвведіть назву пулу, що відображатиметься у моделері —Часткове оновлення даних. -
У полі
Process idвведіть ідентифікатор бізнес-процесу —partially-data-update. -
У полі
Process Nameвкажіть бізнес-назву процесу —Часткове оновлення даних.

-
2.2. Моделювання стартової форми
На цьому етапі необхідно змоделювати стартову форму для внесення даних.
| Цей бізнес-процес ініційований не стартовою подією, а стартовою формою, яка відразу заповнюється даними користувача. |
Для налаштування стартової форми виконайте наступні кроки:
-
На панелі інструментів, зліва, знайдіть елемент (коло) CreateStartEvent та перетягніть його до панелі моделювання.
-
На панелі налаштувань справа відкрийте вкладку General:
-
У полі
Idвкажіть ідентифікатор елемента. Наприклад,addPersonalProfile. -
У полі
Nameвведіть назву початкової події —Внесення даних учня. -
У полі
Initiatorвведітьinitiator.initiator— спеціальна змінна, що встановлюється для користувача, який розпочав процес.

-
-
Перейдіть до вкладки Forms. У полі
Form Keyвведіть ключ форми бізнес-процесу —add-person-profile.
2.3. Моделювання форми для підпису даних КЕП
На цьому етапі необхідно змоделювати користувацьку форму для підпису внесених даних КЕП. Тобто ми передаємо дані для підпису КЕП зі стартової форми до форми підписання даних. Дані передаємо через функцію submission() у полі Form data pre-population.
-
Змоделюйте користувацьку задачу (User form) для підпису даних профілю користувача за допомогою КЕП та пов’яжіть її з формою бізнес-процесу параметром
Form key. -
На панелі налаштувань справа сконфігуруйте такі параметри:
-
У полі
Idвкажіть ідентифікатор задачі —signPersonalProfile. Він є ключем визначення задачі (task definition key). -
У полі
Nameвведіть назву задачі. Наприклад,Підписання даних учня. -
У полі
Form keyвведіть ключ форми бізнес-процесу —sign-person-profile. -
У полі
Assigneeвкажіть змінну, що використовується для зберігання користувача, який запустив екземпляр процесу, —${initiator}. -
У полі
Form data pre-populationвкажіть дані, які необхідно передати зі стартової форми для підпису. Для цього використовуйте функціюsubmission()—${submission('addPersonalProfile').formData}.
-
2.4. Моделювання задачі скриптування "Підготовка даних до запису (transient var)"
Внесені на формі та підписані КЕП дані передаються задачі скриптування (Script task), де використовується groovy-скрипт, який формує із цих даних JSON-об’єкт і записує його до змінної createPersonPayload.
-
Створіть нову задачу, визначте її тип, натиснувши іконку ключа та обравши з меню пункт Script Task (Задача скриптування).
-
На панелі налаштувань справа заповніть наступні поля:
-
У полі
Nameвкажіть назву задачі —Підготовка даних для запису (transient var). -
У полі
Script Formatвкажіть формат скрипту —groovy. -
У полі
Script Typeвкажіть тип скрипту —Inline Script. -
У полі
Scriptвведіть безпосередньо groovy-скрипт:Example 2. Приклад. Groovy-скрипт, що формує JSON-об’єкт для подальшого запису до БДdef formData = submission('signPersonalProfile').formData def cephData = [:] cephData['secondName'] = 'Іванович' cephData['lastName'] = formData.prop('lastName').value() cephData['firstName'] = formData.prop('firstName').value() cephData['birthday'] = formData.prop('birthday').value() def createPersonPayload = S(cephData, 'application/json') execution.removeVariable('createPersonPayload') set_transient_variable('createPersonPayload', createPersonPayload)
-
-
В результаті виконання задачі, у виводі отримуємо сформований JSON, збережений до змінної
createPersonPayload, що надалі використовуватиметься у бізнес-процесі.Example 3. Приклад. Сформований JSON-об’єкт, збережений до змінної 'createPersonPayload'{ "secondName": "string", "firstName": "string", "lastName": "string", "birthday": "2022-02-16T13:17:10.952Z" }
2.5. Моделювання Call Activity для підпису даних системним ключем
Далі необхідно створити Call Activity для виклику глобального підпроцесу підпису даних системним ключем. Call Activity використовує змінну createPersonPayload, дані з якої передаються до підпроцесу для подальшого їх підпису.
В результаті виконання підпроцесу, викликаного у Call Activity, дані підписуються системним Ceph-ключем. Ключ зберігається до змінної createPersonPayloadDerivedKey.
-
Змоделюйте елемент Call Activity.
-
Перейдіть до панелі налаштувань справа та застосуйте делегат System digital signature. Для цього оберіть відповідний шаблон із каталогу (
Open Catalog).Приклад налаштування делегата System digital signature наведено за посиланням. -
Виконайте подальші налаштування:
-
У полі
Nameвкажіть назву елемента —Підписати дані системним ключем. -
У полі
Input dataвкажіть вхідні дані, які необхідно передати підпроцесу, що викликатиметься —${createPersonPayload}. -
У полі
Output variable nameвведіть назву змінної, до якої буде записано системний Ceph-ключ —createPersonPayloadDerivedKey. Він потрібний для додаткового системного підпису у Фабриці даних.Ідентифікатор підпроцесу, що викликатиметься, передається у полі Called Elementі має стале значенняsystem-signature-bp. Ці та деякі інші налаштування "вшито" до шаблону з метою спрощення моделювання.
-
2.6. Моделювання сервісної задачі для створення сутності в базі даних
Надалі дані використовуються у сервісній задачі для створення профілю користувача.
У задачі необхідно застосувати делегат для створення сутності у базі даних (Create entity in data factory), використавши підписані дані (Payload) зі змінної ${createPersonPayload}, та надіслати запит до відповідного API-ендпоінту (ресурсу) person-profile.
Разом із даними передається токен доступу до ресурсу, КЕП і ключ для системного підпису.
-
Змоделюйте нову задачу.
-
Визначте її тип, натиснувши іконку ключа та обравши з меню пункт Service Task (сервісна задача).
-
Перейдіть до панелі налаштувань справа та застосуйте делегат Create entity in data factory. Для цього оберіть відповідний шаблон із каталогу (
Open Catalog). -
Виконайте подальші налаштування:
-
У полі
Nameвкажіть назву задачі. Наприклад,Зберегти дані в БД. -
У полі
Resourceвкажіть ресурс (API-ендпоінт), куди необхідно виконати запит —person-profile.На рівні API ендпоінт виглядає наступним чином: /<resource name>, де<resource name>— назва ресурсу. Тобто у поліResourceнеобхідно ввести значення, вказане після косої риски (/). -
У полі
Payloadвведіть тіло запита — JSON-об`єкт, тобто дані зі змінної${createPersonPayload}, які необхідно зберегти до Фабрики даних.Майте на увазі, що необхідно попередньо побудувати цей JSON-об`єкт, тобто payload, в рамках задачі скриптування. -
У полі
X-Access-Tokenвкажіть токен доступу до ресурсу —${completer('signPersonalProfile').accessToken}.Токен доступу береться з АБО ініціатора (наприклад,
${initiator().accessToken}), АБО виконавця задачі (наприклад,${completer('taskDefinitionId').accessToken}):-
Якщо перед сервісною задачею у бізнес-процесі немає жодної користувацької задачі, використовуємо токен ініціатора процесу (initiator).
-
Якщо перед сервісною задачею є користувацька задача, використовуємо токен виконавця задачі (completer).
Таким чином ми від імені користувача, який АБО запустив бізнес-процес, АБО виконав користувацьку задачу, створюємо сутність у базі даних.
-
-
У полі
X-Digital-Signature-sourceвкажіть джерело цифрового підпису (КЕП), тобто передайте функціїsign_submission()ID користувацької форми, де застосовували КЕП —${sign_submission('signPersonalProfile').signatureDocumentId}. -
У полі
X-Digital-Signature-Derived-sourceвкажіть джерело системного підпису, тобто змінну, з якої необхідно взяти системний ключ, —${createPersonPayloadDerivedKey}. -
У полі
Result variableвкажіть назву змінної, до якої необхідно зберегти відповідь від API, —response.В результаті виконується транзакція, яка створює сутність із даними профілю користувача у базі даних. 
-
2.7. Моделювання сервісної задачі для пошуку сутності в базі даних
Далі необхідно знайти внесені дані у БД. Тобто ми використовуємо критерій пошуку (search condition) для пошуку даних, і шукаємо особу за прізвищем, щойно записаним до БД. Тобто нам треба знайти ID користувача за певним критерієм пошуку, а саме за ключем lastName.
Результат запишеться до змінної response.
-
Змоделюйте нову задачу.
-
Визначте її тип, натиснувши іконку ключа та обравши з меню пункт Service Task (сервісна задача).
-
Перейдіть до панелі налаштувань справа та застосуйте делегат Create entity in data factory. Для цього оберіть відповідний шаблон із каталогу (
Open Catalog). -
Виконайте подальші налаштування:
-
У полі
Nameвкажіть назву задачі. Наприклад,Визначення ID запису. -
Розгорніть секцію Resource:
-
У полі
Local Variable Assigmentувімкніть опцію визначення локальних змінних —On. -
У полі
Variable Assignment Typeіз випадного списку оберіть тип призначення змінної —String or Expression. -
У полі
Variable Assignment Valueвведіть значення локальної змінної —person-profile-equal-last-name. Це назва критерію пошуку (search condition) для ресурсу на рівні Фабрики даних для відповідного представлення (view).
-
-
Розгорніть секцію Search variables:
-
У полі
Local Variable Assigmentувімкніть опцію визначення локальних змінних —On. -
У полі
Variable Assignment Typeіз випадного списку оберіть тип призначення змінної —Map, тобто пари "ключ-значення". -
Натисніть
Add Entry(+) та додайте нову пару:-
у полі
KeyвведітьlastName, тобто ключ для пошуку параметра у БД. Це дозволить передати параметр пошуку до ресурсу (API-ендпоінт для пошуку даних). -
у полі
Valueвведіть дані користувацької форми, де параметрlastNameбув введений, —${submission('signPersonalProfile').formData.prop('lastName').value()}.
-
-
-
Розгорніть секцію Access Token. Введіть токен доступу до ресурсу —
${completer('signPersonalProfile').accessToken}.Токен доступу береться з АБО ініціатора (наприклад,
${initiator().accessToken}), АБО виконавця задачі (наприклад,${completer('taskDefinitionId').accessToken}):-
Якщо перед сервісною задачею у бізнес-процесі немає жодної користувацької задачі, використовуємо токен ініціатора процесу (initiator).
-
Якщо перед сервісною задачею є користувацька задача, використовуємо токен виконавця задачі (completer).
Таким чином ми від імені користувача, який АБО запустив бізнес-процес, АБО виконав користувацьку задачу, виконуємо пошук сутності у базі даних.
-
-
У полі
Result Variableвкажіть назву транзитної змінної, до якої буде збережено результат, отриманий в результаті запита, —response.
-
2.8. Моделювання задачі скриптування для отримання даних учня
На цьому етапі необхідно за допомогою скрипту отримати id елемента із транзитної змінної response попередньої задачі. Це необхідно для того, щоб перезаписати результат до іншої, НЕ транзитної, змінної, де і зберігатиметься отриманий ID. Нова змінна використовуватиметься далі, під час операції часткового оновлення сутності в БД.
-
Створіть нову задачу, визначте її тип, натиснувши іконку ключа та обравши з меню пункт Script Task (Задача скриптування).
-
На панелі налаштувань справа заповніть наступні поля:
-
У полі
Nameвкажіть назву задачі —Отримання даних учня. -
У полі
Script Formatвкажіть формат скрипту —groovy. -
У полі
Script Typeвкажіть тип скрипту —Inline Script. -
У полі
Scriptвведіть безпосередньо groovy-скрипт:Example 4. Приклад. Groovy-скрипт, що отримує ID сутності за параметром і перезаписує його до НЕ транзитної змінноїresponse.responseBody.elements().get(0).prop('personProfileId').value()Тобто скрипт отримує значення першого елемента зі змінної response. -
У полі
Result Variableвкажіть значення нової змінної для перезапису ID.
-
2.9. Моделювання користувацької форми для редагування даних
На цьому етапі необхідно змоделювати форму, на якій користувач зможе внести оновлену інформацію щодо профілю учня.
-
Змоделюйте користувацьку задачу (User form) для підпису даних профілю користувача за допомогою КЕП та пов’яжіть її із формою бізнес-процесу параметром
Form key. -
На панелі налаштувань справа сконфігуруйте такі параметри:
-
У полі
Idвкажіть ідентифікатор задачі —editPersonalProfile. Він є ключем визначення задачі (task definition key). -
У полі
Nameвведіть назву задачі. Наприклад,Редагування даних учня. -
У полі
Form keyвведіть ключ форми бізнес-процесу —edit-person-profile. -
У полі
Assigneeвкажіть змінну, що використовується для зберігання користувача, який запустив екземпляр процесу, —${initiator}. -
У полі
Form data pre-populationвкажіть дані, які необхідно редагувати, —${submission('addPersonalProfile').formData}.

-
2.10. Моделювання користувацької форми для підпису змінених даних КЕП
На цьому етапі необхідно змоделювати форму для підпису внесених змін КЕП.
-
Змоделюйте користувацьку задачу (User form) для підпису даних профілю користувача за допомогою КЕП та пов’яжіть її із формою бізнес-процесу параметром
Form key. -
На панелі налаштувань справа сконфігуруйте такі параметри:
-
У полі
Idвкажіть ідентифікатор задачі —signEditedPersonalProfile. Він є ключем визначення задачі (task definition key). -
У полі
Nameвведіть назву задачі. Наприклад,Підписати змінені дані. -
У полі
Form keyвведіть ключ форми бізнес-процесу —sign-edited-person-profile. -
У полі
Assigneeвкажіть змінну, що використовується для зберігання користувача, який запустив екземпляр процесу, —${initiator}. -
У полі
Form data pre-populationвкажіть відредаговані дані, які необхідно підписати КЕП, —${submission('editPersonalProfile').formData}.

-
2.11. Моделювання задачі скриптування для формування об’єкта зі зміненими даними
Внесені на формі та підписані КЕП дані передаються задачі скриптування (Script task), де використовується groovy-скрипт, який формує із цих даних JSON-об’єкт і записує його до змінної updatePersonPayload.
-
Створіть нову задачу, визначте її тип, натиснувши іконку ключа та обравши з меню пункт Script Task (Задача скриптування).
-
На панелі налаштувань справа заповніть наступні поля:
-
У полі
Nameвкажіть назву задачі —Підготовка даних для запису (transient var). -
У полі
Script Formatвкажіть формат скрипту —groovy. -
У полі
Script Typeвкажіть тип скрипту —Inline Script. -
У полі
Scriptвведіть безпосередньо groovy-скрипт:Example 5. Приклад. Groovy-скрипт, що формує JSON-об’єкт для подальшого запису до БДdef formData = submission('signEditedPersonalProfile').formData def cephData = [:] cephData['lastName'] = formData.prop('lastName').value() cephData['firstName'] = formData.prop('firstName').value() cephData['birthday'] = formData.prop('birthday').value() set_transient_variable('updatePersonPayload', S(cephData, 'application/json'))
-
2.12. Моделювання Call Activity для підпису оновлених даних системним ключем
Далі необхідно створити Call Activity для виклику глобального підпроцесу підпису даних системним ключем. Call Activity використовує змінну updatePersonPayload, дані з якої передаються до підпроцесу для подальшого їх підпису.
В результаті виконання підпроцесу, викликаного у Call Activity, дані підписуються системним Ceph-ключем. Ключ зберігається до змінної updatePersonPayloadDerivedKey.
-
Змоделюйте елемент Call Activity.
-
Перейдіть до панелі налаштувань справа та застосуйте делегат System digital signature. Для цього оберіть відповідний шаблон із каталогу (
Open Catolog).Приклад налаштування делегата System digital signature наведено за посиланням. -
Виконайте подальші налаштування:
-
У полі
Nameвкажіть назву елемента —Підписати дані системним ключем. -
У полі
Input dataвкажіть вхідні дані, які необхідно передати підпроцесу, що викликатиметься —${updatePersonPayload}. -
У полі
Output variable nameвведіть назву змінної, до якої буде записано системний Ceph-ключ —updatePersonPayloadDerivedKey. Він потрібний для додаткового системного підпису у Фабриці даних.Ідентифікатор підпроцесу, що викликатиметься, передається у полі Called Elementі має стале значенняsystem-signature-bp. Ці та деякі інші налаштування "вшито" до шаблону з метою спрощення моделювання.
-
2.13. Моделювання сервісної задачі для часткового оновлення сутності відповідно до внесених змін
На цьому етапі необхідно змоделювати сервісну задачу для оновлення сутності відповідно до внесених на формі змін. Це можна зробити за допомогою спеціального делегата.
Розширення Update entity in data factory partially — делегат для часткового оновлення сутності у фабриці даних, який налаштовується за допомогою розробленого однойменного шаблону Update entity in data factory partially (dataFactoryConnectorPartialUpdateDelegate.json).
| Перед налаштуванням шаблону в Camunda Modeler переконайтеся, що папка із застосунком resources → element-templates містить файл dataFactoryConnectorPartialUpdateDelegate.json. |
-
Створіть Service Task.
-
На панелі налаштувань справа натисніть кнопку
Open Catalog, оберіть відповідний шаблон Update entity in data factory partially зі списку та натиснітьApplyдля підтвердження.
-
Сконфігуруйте обраний шаблон:
-
У полі
Nameвкажіть назву задачі. Наприклад,Часткове оновлення виконанно. -
У полі
Resourceвкажіть ресурс, тобто назву ендпоінту, до якого необхідно звернутися, —person-profile.На рівні API ендпоінт виглядає як /partial/<resource-name>/<resource-id>, де<resource-name>— назва ресурсу, а<resource-id>— ідентифікатор ресурсу у Фабриці даних. У поліResourceнеобхідно вказати значення між/partialта/<resource-id>, без косої риски (/). -
У полі
Resource idвкажіть ідентифікатор ресурсу, тобто сутності у Фабриці даних, яку необхідно оновити. Наприклад,{id}.Ідентифікатор ресурсу визначається у форматі
UUID. Його можна передати як змінну, взяту із попередніх задач бізнес-процесу, або напряму — якf7dc68fe-98e1-4d95-b80f-df5ce42cebb9. -
У полі
Payloadвведіть тіло запита — JSON-структуру із параметрами, які необхідно оновити у Фабриці даних. Наприклад,${updatePersonPayload}. -
У полі
X-Access-Tokenвведіть токен доступу до ресурсу. Наприклад,${completer('signEditedPersonalProfile').accessToken}.Токен доступу береться з АБО ініціатора (наприклад,
$initiator().accessToken}), АБО виконавця останньої користувацької задачі (наприклад,${completer('taskDefinitionId').accessToken}). -
У полі
X-Digital-Signature sourceвкажіть джерело для Ceph-документа, де зберігається підпис користувача, накладений на дані UI-форми при внесенні, —${sign_submission('signEditedPersonalProfile').signatureDocumentId}. -
У полі
X-Digital-Signature-Derived sourceвкажіть джерело для Ceph-документа, де зберігається системний підпис, автоматично накладений на тіло запита, —${updatePersonPayloadDerivedKey}. -
У полі
Result variableвкажіть назву змінної процесу, до якої необхідно записати результат (за замовчуванням —response).

-
3. Імплементація на рівні API
На рівні API Фабрики даних реалізовано окремий ендпоінт для роботи із методом PATCH для часткового оновлення сутності у базі даних.
- Метод та ресурс:
PATCH /partial/<resource-name>/<resource-id>
- Тіло запита:
{
"firstName":"Іван",
"lastName":"Сидоренко",
"birthday":"2020-01-01"
}
4. Імплементація на рівні моделі даних
На рівні структури даних, у файлі createSearchConditions.xml необхідно додати відповідний changeSet із тегом <ext:partialUpdate>. Це дозволить автоматично створити окремий PATCH-ендпоінт на рівні API для підтримки функції часткового оновлення сутності.
Тег <ext:partialUpdate> необхідно додати для кожної таблиці.
|
<changeSet author="registry owner" id="partial update person_profile">
<ext:partialUpdate>
<ext:table name="person_profile">
<ext:column name="last_name"/>
<ext:column name="first_name"/>
<ext:column name="birthday"/>
</ext:table>
</ext:partialUpdate>
</changeSet>
