Часткове оновлення сутності у Фабриці даних
- 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>