Часткове оновлення сутності у Фабриці даних

ЗМІСТ

1. Загальний опис

Для всіх таблиць у Фабриці даних, з якими взаємодіють сервіси, на Платформі використовується 4 основних HTTP-методи: POST, GET, PUT та DELETE.

Для оновлення сутності у Фабриці даних використовується метод PUT та відповідний імплементований делегат Update entity in data factory. При використанні PUT, у тілі запита необхідно вказувати значення усіх полів таблиці, навіть тих, які оновлення не потребують. Така поведінка передбачена для методу PUT за замовчуванням.

Example 1. Приклад

Наприклад, маємо таблицю, яка містить 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. Створення пулу для бізнес-процесу

Найперше, необхідно змоделювати пул для бізнес-процесу. Для цього виконайте такі налаштування:

  1. Відкрийте додаток Camunda Modeler та створіть нову діаграму BPMN. Для цього у лівому верхньому куті натисніть меню FileNew FileBPMN Diagram.

    bp 1

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

    bp 2

  3. Заповніть наступні поля відповідними значеннями:

    • У полі Participant Name введіть назву пулу, що відображатиметься у моделері — Часткове оновлення даних.

    • У полі Process id введіть ідентифікатор бізнес-процесу — partially-data-update.

    • У полі Process Name вкажіть бізнес-назву процесу — Часткове оновлення даних.

    bp partial update 1

2.2. Моделювання стартової форми

На цьому етапі необхідно змоделювати стартову форму для внесення даних.

Цей бізнес-процес ініційований не стартовою подією, а стартовою формою, яка відразу заповнюється даними користувача.

Для налаштування стартової форми виконайте наступні кроки:

  1. На панелі інструментів, зліва, знайдіть елемент (коло) CreateStartEvent та перетягніть його до панелі моделювання.

  2. На панелі налаштувань справа відкрийте вкладку General:

    • У полі Id вкажіть ідентифікатор елемента. Наприклад, addPersonalProfile.

    • У полі Name введіть назву початкової події — Внесення даних учня.

    • У полі Initiator введіть initiator.

      initiator — спеціальна змінна, що встановлюється для користувача, який розпочав процес.

    bp partial update 2

  3. Перейдіть до вкладки Forms. У полі Form Key введіть ключ форми бізнес-процесу — add-person-profile.

    bp partial update 3

2.3. Моделювання форми для підпису даних КЕП

На цьому етапі необхідно змоделювати користувацьку форму для підпису внесених даних КЕП. Тобто ми передаємо дані для підпису КЕП зі стартової форми до форми підписання даних. Дані передаємо через функцію submission() у полі Form data pre-population.

  1. Змоделюйте користувацьку задачу (User form) для підпису даних профілю користувача за допомогою КЕП та пов’яжіть її з формою бізнес-процесу параметром Form key.

  2. На панелі налаштувань справа сконфігуруйте такі параметри:

    • У полі Id вкажіть ідентифікатор задачі — signPersonalProfile. Він є ключем визначення задачі (task definition key).

    • У полі Name введіть назву задачі. Наприклад, Підписання даних учня.

    • У полі Form key введіть ключ форми бізнес-процесу — sign-person-profile.

    • У полі Assignee вкажіть змінну, що використовується для зберігання користувача, який запустив екземпляр процесу, — ${initiator}.

    • У полі Form data pre-population вкажіть дані, які необхідно передати зі стартової форми для підпису. Для цього використовуйте функцію submission() — ${submission('addPersonalProfile').formData}.

      bp partial update 4

2.4. Моделювання задачі скриптування "Підготовка даних до запису (transient var)"

Внесені на формі та підписані КЕП дані передаються задачі скриптування (Script task), де використовується groovy-скрипт, який формує із цих даних JSON-об’єкт і записує його до змінної createPersonPayload.

  1. Створіть нову задачу, визначте її тип, натиснувши іконку ключа та обравши з меню пункт Script Task (Задача скриптування).

  2. На панелі налаштувань справа заповніть наступні поля:

    • У полі 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)

      bp partial update 5

  3. В результаті виконання задачі, у виводі отримуємо сформований 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.

  1. Змоделюйте елемент Call Activity.

  2. Перейдіть до панелі налаштувань справа та застосуйте делегат System digital signature. Для цього оберіть відповідний шаблон із каталогу (Open Catalog).

    Приклад налаштування делегата System digital signature наведено за посиланням.
  3. Виконайте подальші налаштування:

    • У полі Name вкажіть назву елемента — Підписати дані системним ключем.

    • У полі Input data вкажіть вхідні дані, які необхідно передати підпроцесу, що викликатиметься — ${createPersonPayload}.

    • У полі Output variable name введіть назву змінної, до якої буде записано системний Ceph-ключ — createPersonPayloadDerivedKey. Він потрібний для додаткового системного підпису у Фабриці даних.

      Ідентифікатор підпроцесу, що викликатиметься, передається у полі Called Element і має стале значення system-signature-bp. Ці та деякі інші налаштування "вшито" до шаблону з метою спрощення моделювання.

      bp partial update 6

2.6. Моделювання сервісної задачі для створення сутності в базі даних

Надалі дані використовуються у сервісній задачі для створення профілю користувача.

У задачі необхідно застосувати делегат для створення сутності у базі даних (Create entity in data factory), використавши підписані дані (Payload) зі змінної ${createPersonPayload}, та надіслати запит до відповідного API-ендпоінту (ресурсу) person-profile.

Разом із даними передається токен доступу до ресурсу, КЕП і ключ для системного підпису.

  1. Змоделюйте нову задачу.

  2. Визначте її тип, натиснувши іконку ключа та обравши з меню пункт Service Task (сервісна задача).

  3. Перейдіть до панелі налаштувань справа та застосуйте делегат Create entity in data factory. Для цього оберіть відповідний шаблон із каталогу (Open Catalog).

  4. Виконайте подальші налаштування:

    • У полі 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.

      В результаті виконується транзакція, яка створює сутність із даними профілю користувача у базі даних.

      bp partial update 7

2.7. Моделювання сервісної задачі для пошуку сутності в базі даних

Далі необхідно знайти внесені дані у БД. Тобто ми використовуємо критерій пошуку (search condition) для пошуку даних, і шукаємо особу за прізвищем, щойно записаним до БД. Тобто нам треба знайти ID користувача за певним критерієм пошуку, а саме за ключем lastName. Результат запишеться до змінної response.

  1. Змоделюйте нову задачу.

  2. Визначте її тип, натиснувши іконку ключа та обравши з меню пункт Service Task (сервісна задача).

  3. Перейдіть до панелі налаштувань справа та застосуйте делегат Create entity in data factory. Для цього оберіть відповідний шаблон із каталогу (Open Catalog).

  4. Виконайте подальші налаштування:

    • У полі Name вкажіть назву задачі. Наприклад, Визначення ID запису.

    • Розгорніть секцію Resource:

      • У полі Local Variable Assigment увімкніть опцію визначення локальних змінних — On.

      • У полі Variable Assignment Type із випадного списку оберіть тип призначення змінної — String or Expression.

      • У полі Variable Assignment Value введіть значення локальної змінної — person-profile-equal-last-name. Це назва критерію пошуку (search condition) для ресурсу на рівні Фабрики даних для відповідного представлення (view).

        bp partial update 8

    • Розгорніть секцію Search variables:

      • У полі Local Variable Assigment увімкніть опцію визначення локальних змінних — On.

      • У полі Variable Assignment Type із випадного списку оберіть тип призначення змінної — Map, тобто пари "ключ-значення".

      • Натисніть Add Entry (+) та додайте нову пару:

        • у полі Key введіть lastName, тобто ключ для пошуку параметра у БД. Це дозволить передати параметр пошуку до ресурсу (API-ендпоінт для пошуку даних).

        • у полі Value введіть дані користувацької форми, де параметр lastName був введений, — ${submission('signPersonalProfile').formData.prop('lastName').value()}.

          bp partial update 8 1

    • Розгорніть секцію Access Token. Введіть токен доступу до ресурсу — ${completer('signPersonalProfile').accessToken}.

      Токен доступу береться з АБО ініціатора (наприклад, ${initiator().accessToken}), АБО виконавця задачі (наприклад, ${completer('taskDefinitionId').accessToken}):

      • Якщо перед сервісною задачею у бізнес-процесі немає жодної користувацької задачі, використовуємо токен ініціатора процесу (initiator).

      • Якщо перед сервісною задачею є користувацька задача, використовуємо токен виконавця задачі (completer).

      Таким чином ми від імені користувача, який АБО запустив бізнес-процес, АБО виконав користувацьку задачу, виконуємо пошук сутності у базі даних.

    • У полі Result Variable вкажіть назву транзитної змінної, до якої буде збережено результат, отриманий в результаті запита, — response.

      bp partial update 8 2

2.8. Моделювання задачі скриптування для отримання даних учня

На цьому етапі необхідно за допомогою скрипту отримати id елемента із транзитної змінної response попередньої задачі. Це необхідно для того, щоб перезаписати результат до іншої, НЕ транзитної, змінної, де і зберігатиметься отриманий ID. Нова змінна використовуватиметься далі, під час операції часткового оновлення сутності в БД.

  1. Створіть нову задачу, визначте її тип, натиснувши іконку ключа та обравши з меню пункт Script Task (Задача скриптування).

  2. На панелі налаштувань справа заповніть наступні поля:

    • У полі 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.

      bp partial update 9

2.9. Моделювання користувацької форми для редагування даних

На цьому етапі необхідно змоделювати форму, на якій користувач зможе внести оновлену інформацію щодо профілю учня.

  1. Змоделюйте користувацьку задачу (User form) для підпису даних профілю користувача за допомогою КЕП та пов’яжіть її із формою бізнес-процесу параметром Form key.

  2. На панелі налаштувань справа сконфігуруйте такі параметри:

    • У полі Id вкажіть ідентифікатор задачі — editPersonalProfile. Він є ключем визначення задачі (task definition key).

    • У полі Name введіть назву задачі. Наприклад, Редагування даних учня.

    • У полі Form key введіть ключ форми бізнес-процесу — edit-person-profile.

    • У полі Assignee вкажіть змінну, що використовується для зберігання користувача, який запустив екземпляр процесу, — ${initiator}.

    • У полі Form data pre-population вкажіть дані, які необхідно редагувати, — ${submission('addPersonalProfile').formData}.

    bp partial update 9 1

2.10. Моделювання користувацької форми для підпису змінених даних КЕП

На цьому етапі необхідно змоделювати форму для підпису внесених змін КЕП.

  1. Змоделюйте користувацьку задачу (User form) для підпису даних профілю користувача за допомогою КЕП та пов’яжіть її із формою бізнес-процесу параметром Form key.

  2. На панелі налаштувань справа сконфігуруйте такі параметри:

    • У полі Id вкажіть ідентифікатор задачі — signEditedPersonalProfile. Він є ключем визначення задачі (task definition key).

    • У полі Name введіть назву задачі. Наприклад, Підписати змінені дані.

    • У полі Form key введіть ключ форми бізнес-процесу — sign-edited-person-profile.

    • У полі Assignee вкажіть змінну, що використовується для зберігання користувача, який запустив екземпляр процесу, — ${initiator}.

    • У полі Form data pre-population вкажіть відредаговані дані, які необхідно підписати КЕП, — ${submission('editPersonalProfile').formData}.

    bp partial update 10

2.11. Моделювання задачі скриптування для формування об’єкта зі зміненими даними

Внесені на формі та підписані КЕП дані передаються задачі скриптування (Script task), де використовується groovy-скрипт, який формує із цих даних JSON-об’єкт і записує його до змінної updatePersonPayload.

  1. Створіть нову задачу, визначте її тип, натиснувши іконку ключа та обравши з меню пункт Script Task (Задача скриптування).

  2. На панелі налаштувань справа заповніть наступні поля:

    • У полі 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'))

      bp partial update 11

2.12. Моделювання Call Activity для підпису оновлених даних системним ключем

Далі необхідно створити Call Activity для виклику глобального підпроцесу підпису даних системним ключем. Call Activity використовує змінну updatePersonPayload, дані з якої передаються до підпроцесу для подальшого їх підпису.

В результаті виконання підпроцесу, викликаного у Call Activity, дані підписуються системним Ceph-ключем. Ключ зберігається до змінної updatePersonPayloadDerivedKey.

  1. Змоделюйте елемент Call Activity.

  2. Перейдіть до панелі налаштувань справа та застосуйте делегат System digital signature. Для цього оберіть відповідний шаблон із каталогу (Open Catolog).

    Приклад налаштування делегата System digital signature наведено за посиланням.
  3. Виконайте подальші налаштування:

    • У полі Name вкажіть назву елемента — Підписати дані системним ключем.

    • У полі Input data вкажіть вхідні дані, які необхідно передати підпроцесу, що викликатиметься — ${updatePersonPayload}.

    • У полі Output variable name введіть назву змінної, до якої буде записано системний Ceph-ключ — updatePersonPayloadDerivedKey. Він потрібний для додаткового системного підпису у Фабриці даних.

      Ідентифікатор підпроцесу, що викликатиметься, передається у полі Called Element і має стале значення system-signature-bp. Ці та деякі інші налаштування "вшито" до шаблону з метою спрощення моделювання.

      bp partial update 12

2.13. Моделювання сервісної задачі для часткового оновлення сутності відповідно до внесених змін

На цьому етапі необхідно змоделювати сервісну задачу для оновлення сутності відповідно до внесених на формі змін. Це можна зробити за допомогою спеціального делегата.

Розширення Update entity in data factory partially — делегат для часткового оновлення сутності у фабриці даних, який налаштовується за допомогою розробленого однойменного шаблону Update entity in data factory partially (dataFactoryConnectorPartialUpdateDelegate.json).

Перед налаштуванням шаблону в Camunda Modeler переконайтеся, що папка із застосунком resourceselement-templates містить файл dataFactoryConnectorPartialUpdateDelegate.json.
  1. Створіть Service Task.

  2. На панелі налаштувань справа натисніть кнопку Open Catalog, оберіть відповідний шаблон Update entity in data factory partially зі списку та натисніть Apply для підтвердження.

    partial update 1

  3. Сконфігуруйте обраний шаблон:

    • У полі 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).

    partial update 2

2.14. Моделювання події завершення процесу

Завершіть бізнес-процес. Для цього змоделюйте подію завершення та у полі Name введіть Завершення процесу.

bp partial update 13

3. Імплементація на рівні API

На рівні API Фабрики даних реалізовано окремий ендпоінт для роботи із методом PATCH для часткового оновлення сутності у базі даних.

Example 6. Параметри запита для часткового оновлення сутності у БД
Метод та ресурс:
PATCH /partial/<resource-name>/<resource-id>
Тіло запита:
{
	"firstName":"Іван",
	"lastName":"Сидоренко",
	"birthday":"2020-01-01"
}

4. Імплементація на рівні моделі даних

На рівні структури даних, у файлі createSearchConditions.xml необхідно додати відповідний changeSet із тегом <ext:partialUpdate>. Це дозволить автоматично створити окремий PATCH-ендпоінт на рівні API для підтримки функції часткового оновлення сутності.

Тег <ext:partialUpdate> необхідно додати для кожної таблиці.
Example 7. Приклад. changeSet для часткового оновлення сутності у БД
<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>