Асинхронне завантаження даних до БД
- 1. Проблематика
- 2. Загальний опис
- 3. План дій з налаштування функціональності
- 4. Моделювання структур даних
- 5. Моделювання бізнес-процесу
- 6. Моделювання UI-форм
- 7. Моделювання шаблонів відправлення повідомлень
- 8. Керування обмеженнями щодо розміру файлів
- 9. Результат
1. Проблематика
У минулих реалізаціях системи процес завантаження даних з CSV-файлів виконувався синхронно. Це означає, що кожен запит на завантаження даних повинен бути оброблений і завершений в межах фіксованого часу — максимум 30 секунд. До того ж через обмеження в комунікації між сервісами через брокера повідомлень, максимальний розмір файлу, який міг бути завантажений, становив лише 1 МБ. Це вело до додаткового обмеження: файл міг містити не більше 50 рядків.
Такі обмеження стають значною проблемою, коли виникає потреба обробляти більші набори даних. Великі файли, які перевищують ліміт в один мегабайт або вимагають більше часу для обробки, ніж дозволений таймаут, не можуть бути ефективно завантажені та оброблені. Це обмежувало можливості використання системи для великих та складних наборів даних, зменшуючи її ефективність та масштабованість.
2. Загальний опис
Платформа надає можливості асинхронного завантаження даних. Тепер користувачі отримують значно більше можливостей для ефективної роботи з великими обсягами інформації. Це особливо корисно для тих, хто потребує завантаження й обробки масивних даних, які перевищують стандартні обмеження розміру та часу обробки.
Простими словами: що таке синхронне та асинхронне завантаження даних?
Таким чином, основна відмінність між синхронним і асинхронним завантаженням полягає у способі очікування результату: синхронне завантаження змушує "зачекати", поки асинхронне дозволяє продовжити роботу й отримати результат пізніше. |
Ключові можливості
- Обробка великих обсягів даних
-
Завантажуйте й обробляйте файли, розмір яких значно перевищує 1 МБ, без страху перевищення таймауту обробки.
- Гнучке збереження даних
-
Зберігайте дані з одного файлу у декілька таблиць, що підвищує гнучкість управління даними.
- Ефективність та масштабованість
-
Система підтримує більш ефективну та масштабовану обробку даних, адаптовану до потреб сучасних бізнес-завдань.
3. План дій з налаштування функціональності
-
Використовуйте готові референтні приклади моделювання регламенту реєстру.
Де можна знайти референтні приклади моделювання?
Адміністратор Платформи може розгорнути для вас демо-реєстр — еталонний реєстр, що містить референтні та інші приклади файлів для створення цифрового регламенту. Він містить різноманітні елементи для розробки моделі даних, бізнес-процесів, UI-форм, аналітичної звітності, витягів, сповіщень, зовнішніх інтеграцій та багато іншого.
Детальну інструкцію щодо розгортання демо-реєстру та отримання референтних прикладів моделювання ви знайдете на сторінці Розгортання демо-реєстру із референтними прикладами.
Приклад BPMN-схеми процесу буде доступний у регламенті демо-реєстру за пошуком по ключовим словам — reference-save-array-from-csv-file. Назви форм ви можете знайти всередині відповідних користувацьких задач бізнес-процесу у полі
Form key
. -
Моделювання структур даних: використовуйте тег
<createAsyncLoad>
для асинхронного завантаження даних зі встановленим атрибутом ліміту записів —limit
. -
Моделювання бізнес-процесу: налаштуйте делегат Async Data Load Csv Delegate для асинхронного завантаження даних до БД.
-
Моделювання UI форми: використовуйте компонент Data Import для спрощення імпорту даних.
-
Налаштуйте шаблони відправлення повідомлень зі статусом завантаження даних.
-
Регулюйте обмеження щодо розміру файлу на рівні Control Plane.
4. Моделювання структур даних
Змоделюйте структуру даних для асинхронного завантаження сутностей до БД. Розглянемо приклад завантаження даних до таблиці diplomas
в рамках масиву entityList
. Також для наочності показані приклади інших таблиць і композитна сутність.
Атрибут limit є обов’язковим при створенні createAsyncLoad .
|
<changeSet>
<createTable name="item">
<!-- Опис полів таблиці !-->
</createTable>
<createTable name="demo_entity">
<!-- Опис полів таблиці !-->
</createTable>
<createTable name="diplomas">
<!-- Опис полів таблиці diplomas !-->
</createTable>
<createCompositeEntity name="item_with_references">
<!-- Опис полів складної сутності !-->
</createCompositeEntity>
<createAsyncLoad name="allowedAsyncLoads">
<entityList>
<entity name="item" limit="100"/>
<entity name="item_with_references" limit="1000"/>
<entity name="demo_entity" limit="1000000"/>
<entity name="diplomas" limit="500"/>
</entityList>
</createAsyncLoad>
<deleteAsyncLoad name="removeEntities">
<entityList>
<entity name="demo_entity"/>
<!-- Можна додати або видалити інші сутності при необхідності -->
</entityList>
</deleteAsyncLoad>
</changeSet>
- Пояснення до XML-схеми:
-
Ця структура
changeSet
відображає комплексний підхід до створення та налаштування бази даних для асинхронного завантаження даних. Особливо важливо це для сценаріїв, де необхідно ефективно обробляти великі набори даних або дані, які надходять у великій кількості та з різних джерел.
Структура changeSet
включає:
-
Створення таблиць (
createTable
):-
name="item"
: створює нову таблицю з назвоюitem
. -
name="demo_entity"
: створює іншу таблицю з назвоюdemo_entity
. -
name="diplomas"
: додає таблицюdiplomas
, призначену для специфічних даних, пов’язаних з дипломами.
-
-
Створення складної сутності (
createCompositeEntity
):-
name="item_with_references"
: створює складну сутність для управління взаємопов’язаними даними.
-
-
Визначення асинхронного завантаження (
createAsyncLoad
):-
Набір правил для асинхронного завантаження визначається в
entityList
, включаючи ліміти для кожної сутності (limit
).
-
-
Видалення налаштувань асинхронного завантаження (
deleteAsyncLoad
), за потреби.
|
5. Моделювання бізнес-процесу
Розглянемо референтний приклад бізнес-процесу із завантаженням даних про дипломи.
Процес складається з таких основних етапів:
-
Створення User Task: створення користувацької задачі із використанням шаблону User Form для завантаження CSV-файлу з даними про дипломи.
-
Підпис файлу КЕП: використання шаблону Officer Sign Task для підпису файлу.
-
Обробка файлу: скрипт для обробки файлу і перетворення даних.
-
Створення сервісної задачі: налаштування нового делегата Async Data Load Csv Delegate для відправлення запита на асинхронне завантаження даних.
-
Моделювання сповіщень про статус виконання процедури завантаження даних: використання делегата Send User Notification V2.
5.1. Створення User Task для завантаження даних
-
Створіть User Task для завантаження CSV-файлу та застосуйте шаблон User Form.
-
Виконайте наступні налаштування:
-
ID:
addCsvFileActivity
. -
Form key:
reference-add-diplomas-data-csv-file
.
Це ключ UI-форми, який має відповідати службовій назві форми. За цим ключем користувацька задача бізнес-процесу та UI-форма взаємодіють. -
Assignee:
${initiator}
.
Вкажіть ініціатора процесу.
-
5.2. Підпис файлу КЕП
Змоделюйте користувацьку задачу для підпису файлу з даними про дипломи за допомогою КЕП.
-
Створіть User Task для підпису файлу та застосуйте шаблон Officer Sign Task.
-
Виконайте наступні налаштування:
-
Form key:
reference-sign-diplomas-data-csv-file
.
Це ключ UI-форми, який має відповідати службовій назві форми. За цим ключем користувацька задача бізнес-процесу та UI-форма взаємодіють. -
Assignee:
${initiator}
.
Вкажіть ініціатора процесу. -
Form data pre-population:
${submission('addCsvFileActivity').formData}
. Цей параметр дозволяє передзаповнити дані на формі. Використовуйте функцію submission(), в якій передайте дані із попередньої задачіaddCsvFileActivity
.
-
5.3. Скрипт для обробки файлу
-
Створіть Script Task та застосуйте Groovy-скрипт для обробки вмісту CSV-файлу.
-
Відкрийте Script Editor, вставте необхідний код та натисніть
Підтвердити
.Groovy-скрипт для обробки CSV-файлу
def file = submission('addCsvFileActivity').formData.prop('file').elements().get(0) def id = file.prop('id').value(); def document = load_digital_document(id) def originalMetadata = get_digital_document_metadata(id) def resultFile = [:] resultFile['id'] = id resultFile['checksum'] = originalMetadata.getChecksum() set_transient_variable('file', S(resultFile, 'application/json')) def csvData = new String(document, 'UTF-8') def regex = /\b(\d{4}).(\d{2}).(\d{2})\b/ def modifiedContent = csvData.replaceAll(regex) { match -> def dateParts = match.toList() def year = dateParts[1] def month = dateParts[2] def day = dateParts[3] "${year}-${month}-${day}" } def content = modifiedContent.getBytes('UTF-8') def fileName = "derived_" + originalMetadata.getName() def metadata = save_digital_document(content, fileName) def resultDerivedFile = [:] resultDerivedFile['id'] = metadata.getId() resultDerivedFile['checksum'] = metadata.getChecksum() set_transient_variable('derivedFile', S(resultDerivedFile, 'application/json'))
Скрипт написаний мовою програмування Groovy і призначений для обробки завантаженого CSV-файлу. Він є ключовою частиною бізнес-процесу, дозволяючи ефективно обробляти великі обсяги даних і адаптувати їх до потреб системи.
Розглянемо покрокове пояснення нижче.
Пояснення до скрипту для обробки файлу у бізнес-процесі
- Частина 1: завантаження та ідентифікація файлу
-
def file = submission('addCsvFileActivity').formData.prop('file').elements().get(0) def id = file.prop('id').value();
-
submission('addCsvFileActivity').formData
: отримання даних, введених користувачем на формі для завантаження файлу. -
.prop('file').elements().get(0)
: вибір першого елемента із наданих файлів. -
def id = file.prop('id').value()
: збереження ідентифікатора файлу для подальшої обробки.
Більше деталей про функцію submission() див. у розділі Функція submission(). -
- Частина 2: Завантаження та аналіз вмісту файлу
-
def document = load_digital_document(id) def originalMetadata = get_digital_document_metadata(id)
-
load_digital_document(id)
: завантаження цифрового документа за ідентифікатором. -
get_digital_document_metadata(id)
: отримання метаданих завантаженого документа.
Більше деталей про відповідні JUEL-функції див. у розділах:
-
- Частина 3: створення та збереження похідного файлу
-
def resultFile = [:] resultFile['id'] = id resultFile['checksum'] = originalMetadata.getChecksum() set_transient_variable('file', S(resultFile, 'application/json'))
-
Створення нового словника
resultFile
. -
Збереження ідентифікатора та контрольної суми оригінального файлу в
resultFile
. -
Встановлення тимчасової змінної
file
для передачі даних про оригінальний файл.
-
- Частина 4: Обробка вмісту файлу
-
def csvData = new String(document, 'UTF-8') def regex = /\b(\d{4}).(\d{2}).(\d{2})\b/ def modifiedContent = csvData.replaceAll(regex) { match -> def dateParts = match.toList() def year = dateParts[1] def month = dateParts[2] def day = dateParts[3] "${year}-${month}-${day}" }
-
new String(document, 'UTF-8')
: конвертація вмісту файлу в рядок. -
Використання регулярного виразу для пошуку дат у форматі
YYYY.MM.DD
. -
Зміна формату дат на
YYYY-MM-DD
.
-
- Частина 5: збереження обробленого вмісту як нового файлу
-
def content = modifiedContent.getBytes('UTF-8') def fileName = "derived_" + originalMetadata.getName() def metadata = save_digital_document(content, fileName) def resultDerivedFile = [:] resultDerivedFile['id'] = metadata.getId() resultDerivedFile['checksum'] = metadata.getChecksum() set_transient_variable('derivedFile', S(resultDerivedFile, 'application/json'))
-
getBytes('UTF-8')
: Конвертація обробленого вмісту назад у байти. -
save_digital_document(content, fileName)
: Збереження нового вмісту як окремого файлу. -
Створення нового словника
resultDerivedFile
для збереження даних про похідний файл. -
Встановлення тимчасової змінної
derivedFile
для передачі даних про похідний файл.
Більше деталей про функцію save_digital_document() див. у розділі Функція save_digital_document(). -
5.4. Створення сервісної задачі з делегатом Async Data Load Csv Delegate
-
Створіть сервісну задачу та застосуйте делегат Async Data Load Csv Delegate для асинхронного завантаження даних.
-
Виконайте налаштування делегата:
-
Entity:
diplomas
.
Це поле відповідає назві об’єкта у базі даних — таблиці або складного/композитного об’єкта. -
File:
${file}
.
Структура, яка представляє файл і складається з ключа до файлу і чексуми. -
(Опційно) Derived file:
${derivedFile}
.
У цьому полі вкажіть як змінну ключ похідного файлу та чексуму.Похідний файл — структура, яка представляє файл, створений у бізнес-процесі або в результаті опрацювання оригінального файлу.
Якщо у бізнес-процесі сформовано похідний файл, то дані до БД будуть збережені саме з нього!
-
Access token:
${completer('signCsvFileActivity').accessToken}
.
Вкажіть JWT-токен доступу користувача, що виконав останню користувацьку задачу. -
X-Digital-Signature source:
${sign_submission('signCsvFileActivity').signatureDocumentId}
.
У цьому полі вкажіть джерело цифрового підпису користувача. -
Result variable:
result
.
Визначте змінну, до якої необхідно зберегти результат обробки файлу.
-
{
"payload": {
"file": {
"checksum": "....",
"id": "process/bp-instance-id/uuid"
},
"derivedFile": {
"checksum": "...",
"id": "process/bp-instance-id/uuid"
}
}
}
Результатом виконання цієї задачі буде сформований запит до Kafka API про початок завантаження даних. Після завершення завантаження бізнес-процес отримує повідомлення з відповідним статусом.
5.5. Подієвий шлюз та можливі сценарії бізнес-процесу
Змоделюйте подієвий шлюз (Event-based gateway) та можливі сценарії для надсилання нотифікацій щодо результату асинхронного завантаження даних. Залежно від статусу виконання операції завантаження, бізнес-процес піде за певною гілкою.
-
Змоделюйте подієвий шлюз.
Зображення 1. Подієвий шлюзДетальніше див. Ексклюзивний шлюз, що керується подіями. -
Змоделюйте чотири події для чотирьох можливих сценаріїв обробки:
-
Таймер для повідомлення: налаштування таймера для обробки затримки в завантаженні.
Зображення 2. Повідомлення за таймеромДетальніше про таймери див. на сторінках:
-
Повідомлення про успішне завантаження: обробка успішного завантаження.
Зображення 3. Повідомлення про успішне завантаження -
Повідомлення про помилку з даними: обробка випадків, коли дані не можуть бути завантажені через порушення правил БД.
Зображення 4. Повідомлення про помилку з даними -
Повідомлення про помилку з файлом: обробка помилок, що виникають під час опрацювання файлу.
Зображення 5. Повідомлення про помилку з файлом
-
-
Наступним кроком змоделюйте чотири скриптові задачі для кожного зі сценаріїв. Додайте в кожну задачу скрипт для підготовки даних до надсилання нотифікацій.
Код збереження результату у форматі JSONset_transient_variable('resultJson', S(result, 'application/json'))
Цей код зберігає результат у форматі JSON до тимчасової змінної
set_transient_variable('resultJson', S(result, 'application/json'))
, зокрема:-
set_transient_variable
: ця функція використовується для створення або оновлення тимчасової змінної в контексті поточного виконання бізнес-процесу. Тимчасові змінні, використовуються для зберігання даних, що є актуальними лише протягом одного виконання процесу або певної його частини. -
'resultJson'
: це назва тимчасової змінної, яку створює або оновлює ця команда. -
S(result, 'application/json')
: Цей вираз конвертує дані, що знаходяться в зміннійresult
, у формат JSON. ФункціяS()
є функцією конвертації, яка перетворює об’єктresult
у рядок JSON.'application/json'
вказує на MIME-тип даних, який у цьому випадку є JSON.
-
5.6. Відправлення повідомлень
-
Створіть сервісну задачу та застосуйте делегат Send User Notification V2 для надсилання повідомлень користувачам на основі різних умов і результатів асинхронного завантаження.
Делегат Send User Notification V2 використовується для відправки налаштовуваних повідомлень користувачам системи. Він дозволяє інформувати користувачів про різні події або статуси в рамках бізнес-процесу, такі як завершення задач, помилки обробки або інші важливі сповіщення.
-
Налаштуйте шаблон делегата:
-
Recipient (Одержувач):
-
Опис: ім’я користувача або групи користувачів, яким буде надіслано повідомлення.
-
Приклад: вкажіть
${initiator().userName}
для відправки повідомлення ініціатору процесу.Доступні опції для значень Recipient:
-
${initiator().userName}
— для відправлення повідомлення ініціатору процесу. -
${completer('taskDefinitionId').userName}
— для відправлення повідомлення виконавцю певної задачі.
-
-
-
Realm (Keycloak-реалм):
-
Опис: реалм системи автентифікації та авторизації Keycloak, в якому зареєстровано користувача.
-
Приклад: Оберіть
OFFICER
зі списку ролей. Вказує на те, що повідомлення буде відправлене користувачам реалмуOFFICER
, тобто надавачам послуг/посадовим особам.Доступні опції для значень Realm:
-
OFFICER
-
CITIZEN
-
-
-
Notification Message Template (Шаблон повідомлення):
-
Опис: ідентифікатор шаблону повідомлення, який буде використано для формування тексту повідомлення.
Використайте назву шаблону, який необхідно попередньо змоделювати у регламенті реєстру (див. Моделювання шаблонів відправлення повідомлень). -
Приклад: використайте шаблон
reference-async-load-csv-file-timeout
як ідентифікатор шаблону для сповіщення про таймаут завантаження файлу.
-
-
Notification Template Model (Модель шаблону повідомлення):
-
Опис: дані, які будуть використані для заповнення шаблону повідомлення. Вкажіть дані як змінну за моделлю
${templateModel}
. -
Приклад: використайте змінну
${resultJson}
зі скрипту та передайте JSON-об’єкт із результатами операції для формування тексту повідомлення.
-
-
![bp async load 09](../../_images/bp-modeling/bp/bp-async-data-load/bp-async-load-09.png)
Сервісні задачі для інших можливих сценаріїв розвитку бізнес-процесу конфігуруються за аналогічним підходом, з використання делегата Send User Notification V2. Для кожного сценарію унікальним буде лише шаблон повідомлення — Notification Message Template. Відповідно, якщо ви маєте чотири сценарії, в них застосовані чотири однакові делегати, то ви повинні створити й вказати різний шаблон повідомлення для кожного зі сценаріїв. |
6. Моделювання UI-форм
Розглянемо приклади моделювання UI-форм для завантаження CSV-файлу.
-
Увійдіть до Кабінету адміністратора регламентів > UI-форми.
-
Створіть нову форму для асинхронного завантаження даних. Це можна зробити як в окремій версії-кандидаті, так і в рамках майстер-версії регламенту.
-
Вкажіть назву. Наприклад,
Створення даних про дипломи з асинхронним завантаженням (csv-file)
. -
Вкажіть службову назву —
reference-add-diplomas-data-csv-file
. Назва відповідатиме значення поля Form key відповідної користувацької задачі у бізнес-процесі.
-
-
Перейдіть на вкладку Конструктор, перетягніть компонент Data import до панелі моделювання та налаштуйте його.
-
Детальний опис усіх параметрів компонента доступний на сторінці Компонент Data Import.
-
Дивись також Процес моделювання форм.
-
Перейдіть на вкладку File та визначте мінімальний та максимальний розмір файлу:
-
File Minimum Size:
0KB
.-
Значення має бути додатним числом.
-
Використовуйте крапку як розділовий знак у випадку десяткових дробів.
-
Підтримувані одиниці виміру:
В
,КВ
,МВ
чиGB
. Значення без одиниці виміру буде прочитано в байтах. -
Значення не має перевищувати значення поля File Maximum Size.
-
-
File Maximum Size:
100MB
.-
Значення має бути додатним числом.
-
Використовуйте крапку як розділовий знак у випадку десяткових дробів.
-
Підтримувані одиниці виміру:
В
,КВ
,МВ
чиGB
. Значення без одиниці виміру буде прочитано в байтах. -
Значення не має перевищувати значення за замовчуванням, яке встановив адміністратор реєстру (див. детальніше — Керування обмеженнями на завантаження цифрових документів).
-
-
-
Перейдіть на вкладку Validation.
-
Активуйте параметр Required.
Обов’язкове поле має бути заповнене до того, як форму можна буде відправити. -
У полі Resource for validation вкажіть, який ресурс буде використовуватися для валідації файлу. У нашому випадку —
v2/diplomas
.Ресурсом може бути як назва однієї сутності, так і назва складної сутності пов’язаних таблиць, відносно якої й буде відбуватися валідація даних.
-
-
Відкрийте вкладку API та у полі Property Name вкажіть назву поля для API-ендпоінту —
file
. -
Натисніть
Save
, щоб зберегти зміни. -
Перейдіть на вкладку Запит та перегляньте структуру сформованого запита до Фабрики даних.
У вас є вебформа, призначена для завантаження CSV-файлу. Користувач взаємодіє з цією формою, вибираючи файл для завантаження.
Після вибору файлу та натискання кнопки відправки, форма генерує запит до Фабрики даних. Цей запит представлений у форматі
JSON
. У нашому прикладі запит у режимі preview має наступний вигляд:{ "file": [], "submit": false }
-
-
Змоделюйте наступну UI-форму для підписання даних CSV-файлу КЕП. Використовуйте компонент Text Field.
-
Детальніше про форму підписання даних читайте у розділі Створення форми для підписання даних КЕП.
-
Детальніше про компонент Text Field див. Компонент Text Field.
-
-
Застосуйте зміни до майстер-версії, якщо ви виконували конфігурації у версії-кандидаті.
Детальніше про застосування змін див. Перегляд та управління налаштуваннями версії-кандидата.
Для того, щоб дані були збережені до бази даних, вам необхідно коректно заповнити CSV-файл та завантажити його на форму.
|
7. Моделювання шаблонів відправлення повідомлень
Змоделюйте шаблони надсилання сповіщень користувачам на основі різних умов і результатів завантаження даних у бізнес-процесі. Використовуйте назви шаблонів при налаштуванні делегата Send User Notification V2.
У нашому прикладі бізнес-процесу передбачено чотири сценарії. Для кожного потрібно налаштувати власний шаблон повідомлення. Шаблон є окремим елементом (текою) регламенту реєстру і знаходиться під директорією notifications > канал зв’язку, наприклад, inbox.
Тобто можна налаштувати шаблони нотифікацій для різних каналів зв’язку, за умови, що вони активні. Канал зв’язку inbox активний за замовчуванням. Для налаштування доставлення нотифікацій на електронну пошту, необхідно активувати канал зв’язку email у Кабінеті користувача. Детальніше про це читайте на сторінці Загальний огляд Кабінету користувача. |
Назва шаблону відповідає значенню поля Notification Message Template у налаштуваннях делегата для відправлення повідомлень. У нашому прикладі — це reference-async-load-csv-file-timeout
.
Шаблон містить два конфігураційні файли:
-
notification.ftl — містить текст повідомлення. Наприклад:
Процес з асинхронним завантаженням завершився помилкою за таймаутом
-
notification.yml — містить заголовок повідомлення. Наприклад:
title: "Неуспішне завантаження даних"
Застосуйте зміни до майстер-гілки регламенту реєстру. Детальніше про це можна дізнатися з інструкції Процес розгортання регламенту в Gerrit.
8. Керування обмеженнями щодо розміру файлів
Обмеження на розмір файлів встановлює адміністратор реєстру в адмін-панелі Control Plane. Значення, які встановить розробник регламенту під час моделювання форм, не зможуть перевищити значення, встановлені адміністратором на рівні реєстру.
Детальніше про це описано на сторінці Керування обмеженнями на завантаження цифрових документів |
9. Результат
У результаті усіх вищевказаних налаштувань надавачі послуг зможуть у Кабінеті користувача проходити відповідний бізнес-процес для асинхронного завантаження даних та отримувати сповіщення в активовані канали зв’язку про статус виконання операції завантаження (успішний, неуспішний тощо).
Бізнес-процес можна знайти у розділі Доступні послуги > Референтні бізнес-процеси > Асинхронне завантаження даних в дата-фабрику.