Описание OneBridge

OneBridge - это система управления данными, разработанная для автоматизации сбора, преобразования и выгрузки данных в соответствии с заданными пользователем параметрами.

Система включает три основных компонента: Дизайнер заданий, модуль управления и модуль выполнения заданий.

  • Дизайнер нужен для создания и редактирования сценариев обработки данных.
  • Модуль управления используется для наблюдения за употреблением ресурсов сервера, результатами обработки данных, настройкой отложенного выполнения сценариев, управления пользователями.
  • Модуль выполнения состоит из ядра, которое управляет ресурсами и взаимодействует с внутренней базой данных, и менеджера задач, который нужен для оркестрации задач по выполнению сценариев обработки данных.

Набор готовых алгоритмов обработки упрощает процесс управления данными и ускоряет загрузку и выгрузку данных.

Система может взаимодействовать с различными источниками данных и позволяет проверить, очистить и получить качественные данные для дальнейшего использования.

Пользователи системы - разработчики, которые создают и поддерживают, например, корпоративные хранилища данных и нормативно-справочные информационные системы.

Схема работы Onebridge

Схема работы Onebridge

Содержание раздела:

Функции OneBridge

Система выполняет задания по обработке данных. Для запуска задания пользователю нужно выбрать файл с готовым набором алгоритмов обработки данных, указать параметры запуска и запустить задание в работу.

Взаимодействие пользователя с системой может происходить двумя способами:

  • с помощью веб-приложения - Модуль управления позволяет запустить в работу задания на обработку данных, просмотреть задания в виде графа, отследить данные о состоянии сервера системы, настроить расписания запусков заданий и обработчики событий;
  • через локальное приложение Дизайнер заданий - он используется для создания алгоритмов заданий через графический редактор.

В обоих случаях после запуска задания обрабатываются в Модуле выполнения заданий.

Компоненты OneBridge

Дизайнер заданий

Дизайнер заданий - это локальное приложение для создания, редактирования, отладки и запуска файлов заданий. Подробное описание доступно в разделе Дизайнер заданий.

Создание заданий в Дизайнере происходит с помощью графического интерфейса. Процесс создания задания описан в главе Создание заданий.

Главные компоненты заданий - Шаги - представлены в виде прямоугольников, которые можно соединять друг с другом рёбрами и располагать в рабочей области нужным образом. С помощью Дизайнера задаются параметры запуска, настраиваются соединения с базами данных, определяются метаданные.

Результатом создания, настройки и объединения компонентов является xml-файл с алгоритмом обработки данных, который можно запустить из Дизайнера или из Модуля управления. Обработка заданий происходит в Модуле выполнения.

Модуль управления

Модуль управления предназначен для выбора и запуска в работу заданий на обработку данных, отображения в графическом виде алгоритмов заданий, отслеживания данных о состоянии сервера системы, запуска заданий по графику и администрирования пользователей. Подробнее об этои модуле в разделе Модуль управления.

Модуль управления состоит из нескольких компонентов:

  • на странице «Ресурсы» отображаются показатели рабочего сервера системы и список заданий, находящихся в процессе выполнения;
  • страница «История выполнения» показывает историю запуска заданий на выполнение и развёрнутую информацию о файлах заданий;
  • с помощью страницы «Проекты» можно увидеть дерево проектов, просмотреть подробную информацию о файлах заданий и содержимое выбранного файла в текстовом или графическом виде.
  • Расписания позволяют настраивать отложенный запуск заданий.
  • Обработчики событий могут совершать заданное действие в ответ на выполнение определённого пользователем условия.
  • На странице "Пользователи" доступен просмотр и редактирование информации о пользователях.

Модуль управления обеспечивает:

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

Модуль выполнения заданий

Модуль выполнения заданий обрабатывает данные по алгоритму, который выбрал пользователь, и собирает статистику использования ресурсов сервера. Этот модуль состоит из инструкций по обработке данных и содержит программные интерфейсы для передачи необходимой информации в модуль управления заданиями и взаимодействия с рабочими процессами. Подробнее про модуль выполнения в разделе Модуль выполнения заданий.

Модуль выполнения заданий обеспечивает:

  • загрузку данных из источников - файлы CSV, базы данных;
  • обработку данных по указанному алгоритму - сортировка, фильтрация, преобразование данных;
  • отправку обработанных данных по указанному адресу - запись в файл, в базу данных, в корпоративное хранилище данных;
  • администрирование расписаний и обработчиков событий;
  • распределение нагрузки между рабочими процессами, которые загружают и обрабатывают данные.

Терминология

Шаг – минимальный алгоритм обработки информации.

Задание – алгоритм, последовательность шагов, описанная в файле.

Граф – разновидность задания, наименьшая исполняемая единица рабочего процесса. Графы состоят из шагов, имеющих порты для ввода и вывода данных. Порты шагов в графе соединены линиями - ребрами графа, которые отражают передачу данных между портами шагов.

Входной порт – точка входа потока данных в шаг.

Выходной порт – точка выхода результата обработки данных из шага.

Ребрам назначаются метаданные. Метаданные описывают структуру данных. Они состоят из названий полей, типов данных и их размера.

Задача — это граф, поток заданий или другое действие, которое можно запустить вручную, с помощью расписания или обработчика событий. Задача описывает «что нужно сделать».

Источник данных – это массив информации, откуда данные загружаются в систему для обработки.

Приемник данных – целевая система, куда выгружаются данные после обработки. Это может быть база данных, простой файл, интернет-ресурс и так далее.

Плоский файл – это файл, в котором данные хранятся в виде записей. Записи отделяются друг от друга специальным символом-разделителем. Внутри каждой записи может быть несколько полей разных типов. Поля тоже разделяются символом-разделителем.

Расписание – график запуска заданий. Позволяет настроить запуск заданий в конкретное время.

Обработчик событий - инструмент для отслеживания изменений в системе и совершения запланированных действий.

Установка и активация OneBridge

Установка модуля выполнения

Все описанные ниже действия должны производиться на устройстве с операционной системой Ubuntu (поддерживается верси Ubuntu 22.04.3 LTS), либо на виртуальной машине с ОС Ubuntu.

Персонализированнную ссылку на скачивание вашей версии продукта вы получите после подписания лицензионного договора.

Перед началом работы необходимо установить Wget — (GNU Wget) свободную консольную программу для загрузки файлов по сети.

Затем:

  1. Открыть командную строку и выполнить команды:
  • для скачивания приложения OneBridge с сайта modernsolution.ru:
    wget *ссылка на актуальную версию OneBridge*
  • для установки скачанных файлов приложения OneBridge:
    sudo apt install ./onebridge.deb -y

Вместе с файлами приложения OneBridge будут установлены зависимости из следующего списка: build-essential, linux-libc-dev, pkg-config, libssl-dev, libssl3, libgcc-s1, libc6.

После установки файлы OneBridge будут размещены в директории /opt/OneBridge/bin/.

  1. Перейти в вышеуказанную директорию с помощью команды cd /opt/OneBridge/bin/.
  2. Запустить приложение из директории /opt/OneBridge/bin/, введя команду: ./startup.sh

В случае успешной установки будет получен ответ: Startup.

При первом запуске будет запущен сценарий активации вашей копии продукта. Подробнее процесс описан в разделе Активация OneBridge. После активации нужно запустить приложение повторно.

Для подключения к модулю управления заданиями нужно открыть браузер на этой же операционной системе и ввести в поисковую строку локальный ip-адрес и порт подключения вот таким образом: 127.0.0.1:8000.

Откроется начальная страница приложения, с которой можно перейти на любую другую страницу из меню.

Список рекомендуемых браузеров: Google Chrome, Яндекс Браузер, Opera.

Установка Дизайнера заданий

Дизайнер поставляется в zip-архиве. Архив содержит папки "cash", "config", "projects", "templates" и файл запуска приложения client.exe.

Для запуска достаточно распаковать архив в предпочитаемую директорию файловой системы и запустить файл client.exe.

Все проекты, скачиваемые с сервера и создаваемые локально по умолчанию будут устанавливаться в папку "projects". Файлы в "templates" содержат параметры и описания компонентов и настройки соединений с базами данных. В "config" лежат файлы конфигурации Дизайнера. В "cash" могут создаваться временные файлы, используемые во время работы.

Конфигурация OneBridge

Параметры конфигурации системы указываются в файле config.toml в корневой папке проекта. Возможна настройка таких параметров как: адрес подключения интерфейса, параметры авторизации, расположение файлов с логами запусков заданий и других. В таблицах ниже все настраиваемые в конфиге параметры описаны более подробно.

http

Имя параметраОписание параметраПример значения параметра
addrbind address (адрес интерфейса + порт), приоритет отдаётся значению переменной окружения ONEBRIDGE_HTTP_BIND_ADDRESSaddr = "127.0.0.1:8000"
ui_pathпуть к папке с uiui_path = "../ui/dist"

resources

Имя параметраОписание параметраПример значения параметра
intervalинтервал сбора статистики сервера (равен горизонтальному интервалу между точками на графиках во вкладке ресурсов)interval = 5

execution

Имя параметраОписание параметраПример значения параметра
run_storage.sqliteпуть к файлу с информацией о запусках графовpath = "../data/sqlite-storage/execution_run.sqlite"
run_params_storage.sqliteпуть к хранилищу параметров запусковpath = "../data/sqlite-storage/execution_run_params.sqlite"
worker.embeddedпуть к хранилищу журнала выполнения запусковjob_logs_path = "../data/job-logs"

projects

Имя параметраОписание параметраПример значения параметра
fs.mountedпуть к проектамpath = "../projects"

auth

Имя параметраОписание параметраПример значения параметра
pathпуть к хранилищу пользователейpath = "../data/sqlite-storage/users_storage.sqlite"
exp_longэкспирация длинного токена (рт), в секундахexp_long = 86400
exp_shortэкспирация короткого токена (ат), в секундахexp_short = 86400
at_secretсид для генерации токена доступаat_secret = "87ac0287d16540e3f9cb307327411ffb39bb4008"
rt_secretсид для генерации токена обновленияrt_secret = "390aed9f00981f4a4c9ae2c1a5e4c115d56f6101"
api_tokensспецтокен для доступа ко всем апиapi_tokens = ["test"]
ldap_dnпараметры для подключения к базе ldapldap_dn = "uid={},ou=onebridge,dc=example,dc=org"
ldap_addr ip и порт ldap сервераldap_addr = "127.0.0.1:389"
auth_triesколичество попыток авторизации (после использования всех попыток, пользователь блокируется)auth_tries = 5

Активация OneBridge

Активация позволяет убедиться, что ваша копия OneBridge не используется на нескольких устройствах и содержит заявленную версию продукта.

Чтобы активировать вашу копию OneBridge, нужно будет разместить ключ активации в папке ./data/license. Ключ активации представляет собой файл с расширением .lic, который можно получить от сотрудника поддержки OneBridge. Процедура активации однократная и выполняется только при первом запуске системы.

При первом запуске OneBridge создаст папку ./data/license и сгенерирует файл с вашим machine-id. Путь к файлу будет прописан в консоли. Этот файл нужно будет передать сотруднику поддержки СБАР. В ответ вы получите другой файл, который нужно будет положить в папку рядом с machine-id и повторно запустить установку. В случае успешной проверки указанных файлов OneBridge будет активирован и вы сможене использовать все его функции.

При необходимости активации на новом устройстве, нужно будет повторить процедуру обмена файлами при первом запуске системы на этом устройстве.

Установка ODBC

Для доступа к базам данных OneBridge позволяет использовать ODBC. Для работы с конкретной базой понадобится установить соответствующий драйвер.

Ниже приведён пример установки ODBC и драйверов к нему на Linux.

Установка unixodbc

apt install unixodbc-dev

Установка iodbc

apt install odbcinst

Конфигурация odbc

  • Файл odbcinst.ini содержит информацию о драйверах доступных всем пользователям.
  • Файл odbc.ini содержит информацию о DSN доступных для всех пользователей.

Пример содержимого odbcinst.ini:

[PostgreSQL]  
Description = PostgreSQL driver for Linux & Win32  
Driver = /usr/local/lib/libodbcpsql.so  
Setup = /usr/local/lib/libodbcpsqlS.so  
FileUsage = 1  

Заголовок содержит имя драйвера, в последствии используемое в odbc.ini
Description - описание драйвера
Driver - путь к драйверу
Setup - путь к библиотеке, используемой для установки (важно для GUI)

Пример содержимого odbc.ini:

[PostgreSQL]
Description = Test to Postgres
Driver = PostgreSQL
Trace = Yes
TraceFile = sql.log
Database = nick
Servername = localhost
UserName =
Заголовок - имя DSN
Description - описание DSN
Driver - псевдоним драйвера из odbcinst.ini либо можно указать путь до драйвера
Установка драйверов
Установка драйвера для postgres
Установка драйвера firebird
Password =
Port = 5432
Protocol = 6.4
ReadOnly = No
RowVersioning = No
ShowSystemTables = No
ShowOidColumn = No
FakeOidIndex = No
ConnSettings =

Заголовок - имя DSN
Description - описание DSN
Driver - псевдоним драйвера из odbcinst.ini либо можно указать путь до драйвера

Установка драйверов

Установка драйвера для postgres:

apt-get install odbc-postgresql

Установка драйвера firebird:

apt-get install libfbclient2

Дизайнер заданий

Дизайнер заданий - это локальное приложение для создания и запуска файлов заданий.

Все файлы хранятся на сервере, упорядоченные по проектам. OneBridge поддерживает синхронизацию файлов между Дизайнером и сервером, так что ситуации дублирования или потери изменений исключены. Подробнее об устройстве проектов и синхронизации рассказано в главе Проекты.

Создание и редактирование заданий в Дизайнере происходит с помощью графического интерфейса на вкладке Задание. Главные компоненты заданий - Шаги - представлены в виде прямугольников, которые можно соединять друг с другом рёбрами и располагать в Рабочей области нужным образом. Задание свойств шагов осуществляется через Редактор шага.

Выполнение заданий и отслеживание результатов описано в главе Выполнение заданий.

Результатом изменений в Рабочей области является автоматически создаваемый xml-файл, в котором прописан алгоритм обработки данных. Текст файла отображается на вкладке Источник. Обработка алгоритма происходит в Модуле выполнения заданий.

Интерфейс Дизайнера заданий

Интерфейс Дизайнера состоит из четырёх панелей:

  • Рабочая область со списком компонентов находится в верхней правой части окна. На этой панели вы можете создавать свои графы. Список компонентов служит для выбора компонентов, перемещения их в Рабочую область, соединения их рёбрами. Эта панель имеет две вкладки - Задание и Источник.

  • Панель Обозреватель проектов находится в верхней левой части окна. В этой панели находятся папки и файлы ваших проектов. Вы можете просматривать их, создавать новые объекты и открывать любые файлы двойным щелчком для просмотра их в Рабочей области.

  • Панель Структура задания находится в нижней левой части окна. Панель содержит все части графа, открытого в Рабочей области в данный момент.

  • Панель состояний находится в нижней части окна. Она содержит несколько вкладок с уточняющей информацией.

Обзор панелей Дизайнера заданий

Обзор панелей Дизайнера заданий

Проекты OneBridge

Все проекты и их структуры хранятся на сервере. Файлы находятся на сервере и могут быть скачаны в локальный Дизайнер.

Когда проект создаётся локально в Дизайнере - он появляется и на сервере. Для того, чтобы скачать проект с сервера в Дизайнер, нужно авторизоваться и выбрать нужный проект, тогда он будет скачан.

Обозреватель проектов

В левой части окна Дизайнера находится панель Обозреватель Проектов. На этой панели можно развернуть папки проектов, просмотреть имеющиеся в проектах файлы.

Структура папок проекта внутри Обозревател проектов

Структура папок проекта внутри панели Обозревателя проектов

Каждый из проектов будет иметь стандартную структуру проекта, если её не изменить при создании проекта.

Стандартная структура подразумевает набор подпапок в проекте, которые появляются, если при создании проекта стояла галочка "создать проект по шаблону". Ниже в таблице представлено описание шаблонных подпапок.

ОписаниеСтандартное имя папкиСтандартное имя параметраПример использования параметра
все соединенияconnCONN_DIR${CONN_DIR}
входные данныеdata-inDATAIN_DIR${DATAIN_DIR}
выходные данныеdata-outDATAOUT_DIR${DATAOUT_DIR}
временные данныеdata-tmpDATATMP_DIR${DATATMP_DIR}
графыgraphGRAPH_DIR${GRAPH_DIR}
потоки данныхjobflowJOBFLOW_DIR${JOBFLOW_DIR}
метаданныеmetaMETA_DIR${META_DIR}
параметрыparamPRM_DIR${PRM_DIR}

Так же будет создан файл Workspace.prm, содержащий стандартные параметры проекта.

Создание и подключение проектов

Изначально в Дизайнере не будет проектов, пока не создано подключения к какому либо серверу. После подключения проекты можно скачать с сервера или создать локально.

Чтобы подключится к серверу, нажмите правую кнопку в области панели Project structure и выберите New project в контекстном меню.

В параметрах подключения укажите URL cсервера в формате http://ip-adress:port, логин и пароль пользователя, имеющего доступ. Проверить подключение можно с помощью Test Connection. Затем выберите проект из существующих на сервере или создайте новый. Проверьте имя проекта и завершите подключение.

Подключение к новому проекту

Подключение к новому проекту

Выбор существующего или создание нового проекта

Выбор существующего или создание нового проекта

Размещение проекта

Размещение проекта

Действия с проектом на панели Project structure

Размещение проекта

После скачивания проекта файлы с размером, превышающим 1Mb, будут отображаться со значком Download и постфиксом-downloadable в названии расширения. Это значит, они не скачались вместе с остальными файлами проекта потому что слишком большие. Но их можно скачать принудительно, выбрав в меню файла пункт Download.

Действия с файлом на панели Project structure

Действия с файлом на панели Project structure

Создание графов

Граф OneBridge — это наименьшая исполняемая единица рабочего процесса. В графе описан процесс преобразования данных.

После создания проекта вы можете создать новый граф, выбрав в контекстном меню проекта New grf file.

Задайте имя графа в открывшемся диалоговом окне. Граф будет помещен в выбранный проект. Расширение .grf будет добавлено к заданному имени автоматически. Затем в панели Project structure появится файл new-graph.grf. Он автоматически откроется в рабочей области сразу после создания.

После создания файл открывается в рабочей области

После создания файл открывается в рабочей области

В верхнем меню во вкладке View можно настроить отображение сетки (Grid), прилипание (Sticking) и отображение метаданных на ребрах (Show metadata).

Настройка отображения вспомогательных элементов

Настройка отображения вспомогательных элементов

Далее в этой главе описываются следующие темы:

Размещение компонентов

Чтобы создать граф для обработки данных, нужно наполнить граф компонентами. Все доступные к использованию компоненты находятся на правой панели Компоненты.

Найдите FlatFileReader среди Readers. Перетащите его из списка компонентов в Рабочую область.

Размещение первого компонента в Рабочей области

Размещение первого компонента в Рабочей области

Сделайте то же самое с FlatFileWriter из Writers. Поместите их по порядку, слева направо.

Размещение компонента для записи

Размещение компонента для записи

Добавление заметок

Еще одним видом компонентов являются заметки - в них можно записать дополнительную информацию к графу, например, обьяснить логику работы сложного графа. Заметка всегда располагается под шагами и может служить контейнером для них. Чтобы закрепить шаг на заметке, атрибуту parent присваивается значение guiName шага - parent="Note0". Во вкладке Ui на шаге появится значок замка, это значит, что данный шаг закреплен к заметке.

Компонент "Заметка" можно найти на панели компонентов. Перетащив заметку на рабочую область можно задать ей размер, потянув за правый нижний угол.

Добавление заметки к графу

Добавление заметки к графу

Дважды кликните на область заметки, чтобы открыть редактор текста заметки. Атрибуты заметки настраиваются в редакторе на вкладке Attributes.

Редактирование текста заметки

Редактирование текста заметки

Изменение атрибутов заметки

Изменение атрибутов заметки

Когда граф и все входные данные для него готовы, можно запустить его в работу. Запуск и выполнение подробно описаны в следующей главе - "Выполнение заданий".

Редактор шагов

Настройка шага в Редакторе

Настройка шага в Редакторе

Соединение компонентов рёбрами

Теперь нужно соединить компоненты ребром. Для этого есть два способа:

  • Можно нажать на выходной порт FlatFileReader, появится незакреплённое ребро. Перетащите свободный конец ребра на входной порт FlatFileWriter.
  • Быстрое соединение - зажать курсором выходной порт первого шага и протянуть, не отпуская, до входного порта второга шага.

Соединение компонентов ребром

Соединение компонентов ребром

Ребро по-прежнему красного цвета, поскольку ему не назначены метаданные. Чуть ниже описано создание и присвоение метаданных ребру.

Структура задания

Все компоненты, используемые в текущем графе, отображаются на панели Структура задания.

Щелкнув по имени компонента вы перейдёте в редактор выбранного шага.

Список компонентов задания текущего графа

Список компонентов задания текущего графа

Создание и присвоение метаданных ребру

Чтобы передавать данные между компонентами графа, необходимо задать метаданные и присвоить их рёбрам графа. Это возможно несколькими способами:

  1. На панели Outline выберите Metadata -> New Metadata, откроется редактор метаданных.

Здесь нужно задать имя метаданных и разделитель записей. Чуть ниже определить имена, типы и разделитель полей.

Кнопкой + создайте новую запись и укажите ее атрибуты. Сохраните изменения кнопкой Save.

Создание метаданных

Создание метаданных

Чтобы назначить созданные метаданные ребру графа, двойным кликом откройте редактор ребра.

  • Выберите из выпадающего списка нужное имя метаданных, сохраните изменения ребра.
  • Ещё можно зажать одновременно Shift + имя созданной метадаты на панели OutLine, перенести на нужное ребро и отпустить.

Назначение метаданных

Назначение метаданных

Метаданные назначены

Метаданные назначены
  1. На панели Outline щелкните правой кнопкой мыши по Metadata -> Link metadata, чтобы подключить файл с описанием метаданных.

Подключение файла метаданных

Подключение файла метаданных
  1. Скопируйте нужные вам метаданные и вставьте их через контекстное меню.

Метаданные можно копировать - в панели Outline откройте контекстное меню нужной метадаты -> Copy metadata.

В графе, в котрый метадату нужно в ставить, в панели Outline откройте контекстное меню блока Metadata -> Paste metadata.

Если после копирования в графе стало две метадаты с одинаковым именем и это нужно исправить - смените одно из имён в редаторе метаданных.

Назначение параметров

Иногда бывает удобно создать параметр, чтобы переиспользовать его в нескольких местах. Это возможно двумя способами:

  1. Чтобы создать параметр, перейдите в редактор параметров Parameters -> Editor.

Создание параметров

Создание параметров

Созданный параметр можно указать используя синтаксис ${parametr_name}.

Использование параметра

Использование параметра
  1. На панели Outline щелкните правой кнопкой мыши по Parameters -> Link parameters, чтобы подключить файл с описанием параметров.

Подключение файла параметров

Подключение файла параметров

Установка соединения с базой данных

Для корректной работы некоторых шагов нужно создать подключение к базе данных. Это возможно двумя способами:

  1. На панели Outline щелкните правой кнопкой мыши по Connections -> New connection, чтобы создать новое внутреннее соединение с базой.

Для создания соединения выберите один из доступных драйверов и заполните атрибут URL по приведённому шаблону.

Создание соединения

Создание соединения
  1. На панели Outline щелкните правой кнопкой мыши по Connections -> Link connection, чтобы подключить файл, содержащий конфигурацию соединения с нужной базой данных. Заполните атрибут dbConfig, указав путь к файлу с параметрами соединения.

Подключение файла соединения

Подключение файла соединения

Добавление словаря

В словаре можно хранить данные в рамках запуска графа и передавать данные между всеми компонентами этого графа.

Чтобы создать запись словаря, нужно открыть редактор словаря на панели Outline: Dictionary -> Edit dictionary.

Создание словаря

Создание словаря

В редакторе нужно внести имя записи словаря и выбрать его тип. Можно задать значение по-умолчанию.

Редактор словаря

Редактор словаря

Выполнение заданий

Когда граф готов, его можно запустить различными способами:

  • выбрать Run -> Run graph в главном меню;
  • использовать сочетание клавиш Ctrl+R;

Успешное выполнение графа

После запуска графа процесс его выполнения можно увидеть в Консоли:

Вкладка Консоль с обзором выполнения графа

Вкладка Консоль с обзором выполнения графа

На краях рёбер должны появиться цифры, обозначающие количество обработанных записей:

Подсчет проанализированных данных

Подсчет проанализированных данных

Статусы выполнения графа

Исполняемый граф может находиться в одном из следующих состояний:

СтатусСимволОписание
В процессе/In Progress

Статус "В процессе/In Progress"

Процесс выполняется.
Выполнено/Success

Статус "Выполнено/Success"

Работа завершилась без сбоев.
Не выполнено/Failure

Статус "Не выполнено/Failure"

Произошел сбой во время обработки данных.
Отменено/Aborted

Статус "Отменено/Aborted"

Обработка отменена.

Обработка и вывод ошибок

Если при проверке графа или в процессе выполнения задания происходит сбой, ошибки будут выведены в журнал на консоль внизу окна.

Вывод ошибок в консоль

Вывод ошибок в консоль

Модуль управления

Модуль управления - это web-приложение для отслеживания производительности сервера, запуска и наблюдения за выполнением заданий и созданием расписаний запусков заданий.

Каждая страница приложения поделена на три панели:

  • панель меню;
  • рабочая панель;
  • панель дополнительной информации.

Деление экрана на панели

В меню доступны для перехода несколько функциональных разделов: "Ресурсы", "История выполнения", "Проекты", "Расписания", "Обработчики событий" и "Пользователи".

  • На странице ресурсов отображается информация о задействованных ресурсах сервера и его производительности. Информация сгруппирована на нескольких панелях. Периодичность обновления данных можно настроить.
  • На странице истории выполнения отображается история выполнения заданий в виде таблицы, каждая строка которой содержит информацию по отдельному заданию. Данные в таблице можно фильтровать. Доступен просмотр подробных данных по каждому заданию.
  • В дереве проектов доступен просмотр информации о файлах заданий и их запуск на выполнение.
  • С помощью расписаний можно планировать запуск заданий.
  • Обработчики событий реагируют на произошедшие изменения и запускают выполнение назначенных задач.
  • На странице Пользователи доступно администрирование пользователей.
  • На странице Роли осуществляется управление ролями.

В следующих главах описан интерфейс и функционал этих разделов.

Ресурсы

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

Рабочая панель поделена на несколько областей:

  • В блоке «Использование ресурсов» на круговой диаграмме отражается процентное соотношение занятой оперативной памяти сервера ко всей доступной.
  • «Рабочий сервер». Раздел содержит информацию о параметрах рабочего сервера.
  • «Операционная система». Содержит основную информацию об операционной системе.
  • «Производительность». В этом разделе отображаются два линейных графика: «Загрузка памяти» - RAM и «Загрузка ЦП» - CPU.

На панель дополнительной информации выводятся данные о запущенных заданиях.

Интерфейс страницы «Ресурсы»

Деление экрана на панели

В блоке «Производительность» видимую область графиков можно менять, с помощью колеса прокрутки мыши или двигая мышкой ползунок с указанием времени под графиком. Ползунок позволяет установить начало и конец временного интервала по отдельности. Выбор временного отрезка проиллюстрирован на следующем рисунке.

Уменьшение временного отрезка на графиках с помощью ползунка

Уменьшение временного отрезка на графиках с помощью ползунка

Изменение временного отрезка пригодится, чтобы наблюдать изменения производительности на меньшем промежутке времени, так как по умолчанию выводится информация о последних сутках использования.

Наведя указатель мыши на график, вы увидите всплывающую подсказку с описанием ресурсов в выбранный момент времени.

Всплывающая подсказка на графике производительности

Всплывающая подсказка на графике производительности

Для лучшей читаемости каждый из графиков можно включить или отключить, щелкнув его метку над областью графиков.

Метки, управляющие видимостью графиков

Метки, управляющие видимостью графиков

История выполнения

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

Интерфейс страницы «История выполнения»

Интерфейс страницы «История выполнения»

В рабочую область выводится таблица с основной информацией о произведенных запусках заданий: номер запуска, название файла, имя запустившего пользователя, статус и время запуска задания. Процесс, запущенный последним, отображается в таблице выше всех.

Чтобы отфильтровать таблицу по дате или названию файла задания, заполните поля фильтров и используйте кнопку «Фильтровать».

Поля для фильтрации таблицы с историей выполнения заданий

Поля для фильтрации таблицы с историей выполнения заданий

Обзор

Чтобы просмотреть информацию о конкретном задании, нужно кликнуть соответствующую строку в таблице. Откроется панель дополнительной информации с открытой вкладкой «Обзор». Во вкладке будет отображаться информация о выбранном задании.

Если вы попали на вкладку истории выполнения после запуска задания, нажав на уведомление, то просмотр информации по конкретному заданию будет доступен сразу.

На вкладке «Обзор» отображается номер задания, данные о времени выполнения, относительный путь к файлу задания, статус его выполнения и параметры запуска.

Интерфейс вкладки «Обзор»

вкалдка "Обзор"

В таблице ниже описаны данные, отображаемые на вкладке "Обзор".

Имя столбцаОписание
Идентификатор запуска задания, уникальный номер, идентифицирующий запуск задания.
НачалоДата и время начала выполнения задания.
КонецДата и время окончания выполнения задания.
ПродолжительностьДлительность выполнения задания.
Файл заданияОтносительный путь до файла графа.
СтатусСтатус выполнения задания. "Выполнено" - задание выполнено успешно, "В процессе" - задание в данный момент выполняется и "Не выполнено" - задание завершено с ошибкой.
Входные параметрыНаименования и значения входных параметров, которые были использованы при запуске задания.
Тип запускаОтражает триггер, запустивший задание в работу: Вручную/ По событию/ По расписанию
ПроектНазвание проекта, в котором лежит файл графа запускаемого задания.
ПользовательИмя пользователя, который запустил задание.

Инспектор заданий

Графический инструмент «Инспектор заданий», приведенный на рисунке ниже, позволяет пользователю исследовать процесс выполнения задания. Инспектор заданий визуализирует поток данных в виде графа. На графе выводятся компоненты - это шаги алгоритма, они представлены в виде прямоугольников, соединенных линиями. Линии в графе называются рёбрами и отражают потоки данных между компонентами.

Граф может быть очень большим и не помещаться в инспекторе полностью. Чтобы увидеть все компоненты и их связи, нужно перетащить рисунок, зажав его левой кнопкой мыши и потянув, сдвигая в сторону.

Вкладка «Инспектор заданий». Визуальное представление задания, состоящего из нескольких шагов.

Вкладка «Инспектор заданий»

Отслеживание

С помощью "Отслеживания" можно увидеть подробные данные по каждому шагу, используемому в графе. Статусы шагов, количество переданных записей, скорость передачи данных.

Вкладка «Отслеживание»

Вкладка «Отслеживание»

Журнал

На вкладку «Журнал» пишутся логи. Здесь можно будет увидеть ошибку, если она случится в процессе выполнения.

Каждый запуск задания имеет собственный файл журнала. Журнал можно скачать.

Вкладка «Журнал»

Вкладка «Журнал»

Содержимое файла

На вкладку «Содержимое файла» выводится контент файла, актуальный на момент запуска задания.

Вкладка «Содержимое файла»

Вкладка «Содержимое файла»

Перезапуск задания

Для удобства, с любой вкладки панели дополнительной информации можно запустить задание заново с помощью кнопки "Перезапустить".

Если в графе используются параметры, то при перезапуске будут по умолчанию использованы значения из задания, из которого происходит перезапуск. Значения, указанные в файле графа, учтены не будут.

В окне перезапуска можно ввести новые значения параметров, если это необходимо. А также выбрать - использовать актуальную на данный момент версию этого графа или версию из представленного в истории запуска.

Граф с параметрами из истории. Кнопка перезапуска

Вкладка «Содержимое файла»

В окне перезапуска указано историческое значение параметра SECONDS и по умолчанию выбран чекбокс "Использовать текущий файл".

Окно задания параметров перед перезапуском

Вкладка «Содержимое файла»

Значение параметра можно поменять

Вкладка «Содержимое файла»

Перезапущенное задание использует файл графа, актуальный на данный момент и параметры, введенные в окне перезапуска.

Результат перезапуска с новыми значениями параметров

Вкладка «Содержимое файла»

Проекты

Проекты — это место, где хранятся все рабочие файлы. На рабочей панели этой страницы находится каталог проектов, внутри проектов – папки и файлы. На следующем рисунке приведен внешний вид страницы проектов.

Интерфейс страницы «Проекты»

Интерфейс страницы «Проекты»

Чтобы открыть содержимое проекта или папки нажмите знак «+» слева от названия объекта в каталоге.

Если нажать на название элемента каталога, появится панель дополнительной информации в правой части экрана. На ней есть несколько вкладок для просмотра подробной информации об открытом элементе и его содержимом.

Всегда доступна вкладка «Обзор». На ней отображаются данные файла или выбранной директории. Запуск заданий на выполнение производится на этой вкладке.

Для файлов с расширением .grf появляется вкладка «Инспектор заданий». На ней можно увидеть процесс выполнения задания в графическом виде.

Текст файла задания выводится во вкладку «Содержимое файла».

Далее описано создание проектов и управление их содержимым.

Создать проект

Чтобы создать новый проект нажмите кнопку «Создать новый проект» в верхней части рабочей панели на странице «Проекты». Диалог создания проекта показан ниже.

Открытие диалога по созданию нового проекта

Открытие диалога по созданию нового проекта

Откроется диалоговое окно. Задайте название в поле «Имя проекта» и используйте чекбокс "Шаблон", если хотите, чтобы в новом проекте сразу появились папки для удобства. Нажмите кнопку «Создать», чтобы создать проект. Чтобы выйти из диалога без сохранения – нажмите «Закрыть».

В случае создания проекта в верхнем правом углу будет выведено уведомление об этом. Название нового проекта появится в дереве проектов.

Пример шаблонного проекта приведён на рисунке ниже:

Новый проект создан

Новый проект создан

Создать папку

В существующих проектах можно создавать пользовательские папки для упорядочивания файлов внутри ваших проектов.

Для создания папки нажмите на название проекта, в котором нужно создать папку. На панели дополнительной информации отобразится вкладка «Обзор». Откройте список действий с проектом, нажав на троеточие в правой части вкладки. Выберите «Создать папку».

Меню директории при создании папки

Меню директории при создании папки

Отобразится диалоговое окно. Введите имя папки в поле «Имя папки». Нажмите «Создать». Для отмены создания нажмите «Закрыть».

Диалог создания папки

Диалог создания папки

После создания папки в верхнем правом углу появится всплывающее уведомление с названием созданного объекта.

Новая папка создана

Новая папка создана

Создать файл

Файлы можно создавать как внутри проектов, так и внутри папок. Чтобы создать файл, выберите в рабочей панели нужную директорию щелчком мыши. Будет открыта вкладка «Обзор». С помощью троеточия в правом верхнем углу откройте меню директории, выберите «Создать файл».

Меню директории при создании файла

Меню директории при создании файла

Откроется диалог создания файла. Путь к создаваемому объекту будет указан в поле «Создать файл в». Задайте название файла вместе с расширением в поле «Имя файла». При необходимости, внесите содержимое файла в поле «Содержимое файла». Нажмите «Создать». Для отмены создания нажмите «Закрыть».

Диалог создания файла

Диалог создания файла

После создания файла в пустой папке рядом с её значком в дереве проектов появится значок «+». Это значит, что в папке есть объекты. Чтобы посмотреть список объектов, нажмите на «+», директория раскроется и станут видны содержащиеся в ней объекты. Значок «+» при этом изменится на «».

Новый файл создан

Новый файл создан

Расписания

Раздел расписаний позволяет планировать запуск заданий по графику, устанавливаемому пользователем. Периодичность запуска настраивается.

Запланированные расписания представлены в виде таблицы, в которой указан статус расписания (включено/выключено), название расписания и имя запускаемого файла, дата и время последнего и следующего запусков.

Для каждого расписания можно открыть вкладку Обзор и просмотреть подробную информацию - интервал действия, заданные параметры.

Список созданных расписаний

Список расписаний

Каждое расписание представляет собой определение времени и периодичности запуска и указание файла задания и параметров для выполнения. После создания расписания можно редактировать значения его атрибутов, например, приостанавливать его выполнение, изменив статус.

Периодичность запуска расписаний:

  • один раз - нужно задать время выполнения;
  • с интервалом - нужно задать время начала и конца активации;
  • расписание. Для задания такого расписания используется cron-выражение.

CRON-выражение используется для настройки триггера, в основном для повторяющегося срабатывания по расписанию. Оно представляет собой строку, состоящую из 6 или 7 полей, представляющих отдельные значения расписания. Эти поля разделены пробелами и содержат любые разрешенные значения в разных сочетаниях.
CRON-выражение может быть простым, например: * * * * ? *, или более сложным, например: 0/5 14,18,3-39,52 * ? JAN,MAR,SEP MON-FRI 2012-2020

Атрибуты расписаний

НазваниеОбязательныйОписание
Название расписанияда

Пример значения: Schedulename01

Периодичностьда

Пример значения: один раз/интервал/расписание

Время исполнениядаАктуально для периодичности "Один раз".

Пример значения: 14.02.2024 11:00:00

Запускать каждыедаАктуально для периодичности "Интервал".

Пример значения: 5 мин

Выражение cronдаАктуально для периодичности "Расписание".

Пример значения: 0 * 14 * * ? *

Начало активациидаАктуально для периодичности "Интервал" и "Расписание".

Пример значения: 14.02.2024 11:00:00

Конец активациидаАктуально для периодичности "Интервал" и "Расписание".

Пример значения: 14.02.2024 11:15:00

Файл заданиянет

Пример значения: graphs/sort-with-prms.grf

Параметрынет

Пример значения: READ_DIR: /test-cases/data-in/copy01_in.txt

Создать расписание

Чтобы открыть диалог создания расписания нажмите «Новое расписание».

В открывшемся окне введите имя расписания, периодичность запуска, время активации, выберите файл задания, который надо запустить, при необходимости задайте параметры. Нажмите «Создать», чтобы создать расписание.

Диалог создания нового расписания

Диалог создания нового расписания

Расписание будет создано и запущено в заданное время. Созданное расписание можно увидеть в таблице расписаний. Работающие расписания помечены как включенные с помощью синего переключателя. Чтобы выключить расписание – нажмите на переключатель, чтобы он стал серым.

Список запланированных задач

Список запланированных задач

Выполнение расписания можно проверить на странице «История выполнения».

Проверка запуска запланированной задачи в истории выполнения

Проверка запуска запланированной задачи в истории выполнения

Изменить расписание

Для редактирования расписания нажмите значок в виде пишущей ручки на вкладке "Обзор". В открывшемся окне можно изменить тип расписания, время и файл, который будет запущен.

Редактирование расписания

Редактирование расписания

Измененное расписание

Измененное расписание

Чтобы переименовать расписание, воспользуйтесь меню из трёх точек, введите новое имя расписания.

Переименование расписания

Переименование расписания

Удалить расписание

Чтобы удалить расписание, нажмите значок мусорного ведра на вкладке Обзор и подтвердите удаление в появившемся диалоговом окне.

Удаление расписания

Удаление расписания

Обработчики событий

Обработчики событий – это инструменты для отслеживания изменений в системе и совершения запланированных действий. С их помощью можно настроить запуск выполнения определенной задачи, после выполнения указанного события.

Список созданных обработчиков событий

Список созданных обработчиков

Виды обработчиков:

  • обработчики событий заданий привязаны к определенному рабочему процессу и отрабатывают каждый раз, когда рабочий процесс выполняется;
  • обработчики файловых событий отслеживают изменения в файловой системе и реагируют на такие изменения запуском определенной задачи.

Обработчики ждут наступления события и запускают определенное в их настройках действие, если событие происходит. Созданные обработчики отображаются в списке обработчиков событий.

Отслеживаются следующие события:

  • События с заданиями – завершение работы
  • События с файлами – создание, удаление

Список обработчиков содержит следующую информацию:

названиеописание
ВключеноУказывает, включен ли обработчик или отключен. Щелчок по значку включает/отключает обработчик.
Обработчик событияПоказывает имя обработчика, тип задачи и событие, которого ожидает обработчик.
Файл заданияИмя файла, окончание работы которого отслеживается обработчиком.
Последний запускПоказывает дату и время последнего запуска обработчика.

Типы задач, которые можно выполнить с помощью обработчиков:

  • запуск задания;
  • выполнение системной команды.

Таблица атрибутов обработчика событий:

АтрибутОбязательныйОписаниеВозможные значения
name string название слушателя name="listener2000"
enabled bool состояние слушателя. Включён|выключен enabled=true
event string событие, которое слушает слушатель: "Job" или "File"
"event": {
   "job": {
       "finished": {
           "job_file": "/JobsForTests/graph/others/concat.grf"}}}
action string действие, которое необходимо выполнить, когда event завершится
"action": {
"start_job": {
    "job_file": {  "job_file":"/JobsForTests/graph/others/concat.grf",
                    "params": []}}}

Создать обработчик событий

Чтобы настроить обработчик щелкните Новый обработчик на вкладке Обработчики событий. Появится диалоговое окно для внесения атрибутов. Задайте название обработчика, выберите отслеживаемое событие и назначьте действие, которое будет выполнено, когда отслеживаемое событие совершится. Нажмите «Создать».

Создание обработчика

Создание обработчика

Созданный обработчик отобразится в списке.

Список Обработчиков

Список Обработчиков

Отредактировать обработчик событий

Для того чтобы отредактировать обработчик откройте вкладку Обзор, нажав на имя обработчика. На вкладке с подробной информацией выберите кнопку редактирования в виде карандаша. В открывшемся диалоговом окне внесите изменения в обработчик. Изменить можно все кроме названия.

Редактирование обработчика

Редактирование обработчика

Переименовать обработчик событий

Для того, чтобы изменить название обработчика, откройте выпадающее меню, нажав на три точки и выберите Переименовать обработчик. Внесите новое имя обработчика в открывшейся форме.

Переименование обработчика

Переименование обработчика

Удалить обработчик событий

Чтобы удалить обработчик событий нажмите кнопку удаления в виде мусорного ведра, подтвердив удаление в диалоговом окне.

Удаление обработчика

Удаление обработчика

Управление пользователями

В OneBridge учётные записи пользователей создаются и редактируются на странице "Пользователи".

Пользователям можно назначать роли и привилегии для разграничения прав и уровней доступа.

Ролевая модель описана в главе Права доступа.

Управление пользователями OneBridge

Управление пользователями OneBridge

Схема авторизации

В Onebridge возможно существование два типа пользователей:

  • внутренние (метод аутентификации Internal)
  • внешние (метод аутентификации LDAP)

Когда пользователь вводит логин и пароль на странице авторизации, производится проверка принадлежности пользователя к тому или иному существующему типу. Если в списке внутренних пользователей логин не найден - производится проверка в списке пользователей LDAP. Если логин не найден и там, выдается ошибка авторизации. В случае если пользователь найден по логину в одном из списков, сразу производится проверка совпадения паролей, если она пройдена, то пользователь получает ключ авторизации и входит в систему.

Схема авторизации пользователя в OneBridge

Схема авторизации пользователя в OneBridge

Далее описаны возможные действия с учётными записями пользователей:

Создание нового пользователя

Чтобы создать пользователя нажмите Добавить нового пользователя. Появится диалоговое окно для внесения данных.

Внесите обязательную информацию, такую как логин, имя и почту. Нажмите Создать для создания и Закрыть для выхода из диалога без сохранения пользователя.

Создание пользователя

Создание пользователя

Если пользователь создан, появится окно с назначенным ему паролем. Пароль нужно скопировать, чтобы использовать для первой авторизации пользователем.

Сохранение дефолтного пароля пользователя

Сохранение дефолтного пароля пользователя

Всю доступную информацию о пользователе можно просмотреть на вкладке Обзор, кликнув на строку с его именем.

Просмотр информации о пользователе

Просмотр информации о пользователе

В Обзоре отображаются следующие данные о пользователе:

Имя атрибутаОписание
Метод аутентификацииInternal \ LDAP
ЛогинИдентификатор пользователя, может состоять только из букв и цифр. Нельзя поменять после создания.
ИмяИмя пользователя, может состоять только из букв и цифр.
ФамилияФамилия пользователя, может состоять только из букв и цифр.
e-mailАдрес электронной почты пользователя, может состоять из букв, цифр и знаков препинания.
СтатусСтатус пользователя (Активный \ Заблокирован), меняется с помощью синего свитч-переключателя.
Дата последнего входаДата и время, когда пользователь последний раз авторизовался.
Статус последнего входаУспешно \ Не произведен

Изменение записи пользователя

Для изменения данных пользователя воспользуйтесь меню на вкладке Обзор. В открывшемся диалоге внесите изменения, нажмите Сохранить для сохранения изменений и Закрыть, чтобы выйти из диалога без сохранения. Будет показано уведомление об успешном обновлении данных и новые данные отобразятся на вкладке.

Изменение информации о пользователе

Просмотр информации о пользователе

Просмотр обновлённой информации о пользователе

Просмотр информации о пользователе

Включение и отключение пользователей

Созданных пользователей нельзя удалить через интерфейс, но учётные записи пользователей, которые потеряли свою актуальность, можно заблокировать. Для этого нужно кликнуть на синий переключатель, статус пользователя сменится.

Смена статуса учётной записи пользователя

Смена статуса учётной записи пользователя

Сменить пароль

Если пользователь забыл свой пароль, администратор с соответствующей ролью может сбросить его пароль через меню на вкладке Обзор.

Сброс пароля от учётной записи пользователя

Сброс пароля от учётной записи пользователя

Новый пароль будет выведен в диалоговое окно. Администратор может скопировать его и передать пользователю. При входе пользователю нужно будет ввести сгенерированный пароль и задать новый.

Копирование нового пароля от учётной записи пользователя

Копирование нового пароля от учётной записи пользователя

Назначение ролей и привилегий

Каждому пользователю можно назначить роли и привилегии. Для настройки ролей пользователя перейдите на вкладку Роли. Чтобы выдать пользователю роль, выделите имя роли в графе "Все роли" и переместите с помощью кнопок управления в графу "Выданные роли". Сохраните изменения.

Назначение ролей пользователю

Назначение ролей пользователю

Привилегии выдаются пользователю на вкладке Привилегии. Возле каждой привилегии есть два чекбокса: левый чекбокс отвечает за привилегии, выданные через роли, присвоенные пользователю. Их можно отредактировать только на вкладке Роли. С помощью правого чекбокса можно выдать привилегию пользователю напрямую. Для этого выделите нужные привилегии, отметив их чекбоксы. Сохраните изменения.

Назначение привилегий пользователю

Назначение привилегий пользователю

Управление ролями и привилегиями

Роли и принадлежащие им привилегии можно править на странице Роли.

Ролевая модель описана в главе Права доступа.

Чтобы создать роль нужно открыть диалог создания роли с помощью кнопки Добавить новую роль. Внести имя роли и её описание, сохранить.

Каждой роли можно назначить суброли и привилегии. Для настройки субролей роли перейдите на вкладку Роли на панели дополнительной информации. Чтобы выдать роли суброль, выделите имя роли в графе Все роли и переместите с помощью кнопок управления в графу Выданные роли. Сохраните изменения.

Назначение субролей роли

Назначение субролей роли

Привилегии выдаются роли на вкладке Привилегии. Кликните на чекбокс рядом с нужной привилегией, чтобы добавить ее в список привилегий конкретной роли. Сохраните изменения.

Назначение привилегий роли

Назначение привилегий роли

Модуль выполнения заданий

Модуль выполнения заданий представляет собой сервер и отвечает за обработку данных, сбор статистики использования ресурсов сервера, оркестрацию выполняемых и заланированных заданий.

Этот модуль состоит из инструкций по обработке данных и содержит программные интерфейсы для передачи необходимой информации в другие модули и взаимодействия с рабочими процессами OneBridge.

В главах этого раздела описано устройство файлов заданий, рассказано о параметрах и метаданных, использууемых для работы и приведено описание всех компонентов, которые используются для обработки данных.

Задания

Задание – это файл с описанием последовательности обработки данных в формате XML. Имеет расширение .grf.

Граф – составляющая задания, наименьшая исполняемая единица рабочего процесса. Графы состоят из шагов, имеющих порты для ввода и вывода данных. Порты шагов в графе соединены линиями - ребрами графа, которые отражают передачу данных между портами шагов.

В этой главе описаны:

Структура файлов заданий OneBridge

В системе определены некоторые элементы, которые стоит использовать для корректной передачи информации и отображения заданий в инспекторе задач.

После декларации следует указать начальный тег корневого элемента документа <Graph>. В этот элемент помещается все описание алгоритма обработки данных, все используемые шаги, ребра и их метаданные.

За ним следуют строки, описывающие дочерние элементы корневого элемента. Два главных дочерних элемента это <Global> и <Phase>. В элементе <Global> описываются метаданные и параметры подключения.

Система OneBridge обрабатывает данные в виде записей. Каждая запись может состоять из нескольких полей разных типов. Метаданные хранят тип данных этих полей. Метаданные являются частью задания, они содержатся в файле задания и их нужно описывать в элементе <Metadata>, чтобы четко определить типы обрабатываемых данных.

Параметры подключения к базе данных, файлы с настройками, можно указать и подключить в элементе <GraphParameters>.

В <Phase> задаются атрибуты шагов задания <Node> и описываются ребра <Edge>. Описание шагов может содержать в себе дочерние элементы <Attr>, в которых описываются методы преобразования записей данных.

Последняя строка файла содержит конечный тег корневого элемента: </Graph>.

На схеме ниже представлена иерархия элементов в файле задания.

Рисунок 1. Схема вложенности элементов заданий в OneBridge.

Элементы заданий

Ниже приведена таблица с описанием возможных элементов файла задания.

ЭлементРодительский элементОписание элемента
Graphнет

Является главным элементом, определяющим граф. Содержит информацию о файле задания.*

Обязательный тег для отрисовки графа в инспекторе заданий.

GlobalGraph

Содержит информацию о файле, не имеет атрибутов. Дочерние элементы:

- Metadata - используемые метаданные;

- GraphParameters – параметры графа;

- Connection – подключения к базам данных.

MetadataGlobalОпределяет тип данных записи
RecordMetadata

Используется для определения символов-разделителей полей и записей для шагов FlatFileReader и FlatFileWriter, которые читают и записывают данные изв плоские файлы.

По умолчанию разделитель полей — "," разделитель строк — "n", если необходимо использовать другие разделители – нужно задать их в элементе Record с помощью конструкции:

<Record fieldDelimiter=";" recordDelimiter="_">

FieldRecord

Содержит имя поля и его тип.

Если задан Record, то все Field должны идти внутри него.

<Field name="y_coord" type="int"/>

GraphParametersGlobalСодержит элементы, в которых хранится информация для подключения к базам данных или путь к файлу для чтения. Может иметь атрибут scopeNonce - дополнительный параметр для защищенных параметров, например, пароля от базы данных.
GraphParameterGraphParameters

Хранит параметры для используемых в файле шагов, например, путь к файлу для шага чтения данных.

Атрибуты элемента описаны в таблице "Атрибуты элемента GraphParameter"

GraphParameterFileGraphParameters

Подключает файл параметров.

Атрибуты описаны в таблице "Атрибуты элемента GraphParameterFile"

ConnectionGlobalХранит параметры подключения к базе данных.
PhaseGraph

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

Каждый граф выполняется параллельно в рамках одного и того же номера фазы; т. е. каждый шаг и каждое ребро с одинаковым номером фазы выполняются одновременно. Если процесс останавливается на какой-то фазе, более высокие фазы не запускаются. Только после успешного завершения всех процессов в рамках одной фазы начнется следующая фаза.

Ребра графа, в которых описывается соединение шагов должны быть описаны в одной фазе с используемыми шагами. То есть нельзя объявлять шаги в одной фазе, а связывать их ребром - в другой.

NodePhaseОписывает атрибуты шага. Атрибуты описаны в таблице "Атрибуты элемента Node"
AttrNodeОписывает логическое выражение для фильтрации и сортировки или метод преобразования данных.
EdgePhaseОписывает связь между шагами графа. Атрибуты описаны в таблице "Атрибуты элемента Edge"

Атрибуты элементов

Для заданий: <GraphParameter> и <GraphParameterFile>

Для шагов:<Node>

Для рёбер:<Edge>

Атрибуты элемента GraphParameter

НазваниеОбязательныйОписаниеВозможные значения
nameдаИмя параметраname="READ_DIR"
valueнетЗначение параметраvalue="test/files/generated"
publicнетПубличность параметраЗначение по умолчанию: public="false"
requiredнетОбязательность указания значения параметра при запуске заданияЗначение по умолчанию : required="false"
secureнетПараметр зашифрованЗначение по умолчанию: secure="false"
  • если public="true" и required="true", тогда value игнорируется;
  • если public="true" и value не задан, тогда required устанавливается в "true";
  • если public="false", то required игнорируется;
  • если public="false", то value должно быть задано;
  • значение name не может содержать в себе подпоследовательность "${".

Атрибуты элемента GraphParameterFile

Атрибут Обязательный Описание Возможные значения
fileURL да Путь к файлу с параметрами

fileURL="${PRM_DIR}/db_01__full_conn.prm"

Атрибуты элемента Node

АтрибутОбязательныйОписаниеВозможные значения
idдаУдобное название шага для указания в атрибутах ребер графа.id="reader"
guiNameнетИмя шага, отражаемое в инспекторе заданий. Может быть любым.guiName="read"
guiXнетКоордината X левого верхнего угла шага для визуального отображения шага в инспекторе задач.guiX="-132"
guiYнетКоордината Y левого верхнего угла шага для визуального отображения шага в инспекторе задач.guiY="212"
typeдаТип шага. Определяет функциональность данного шага.

Все имеющиеся в системе типы шагов:

type="FLAT_FILE_READER"
type="DATABASE_READER"
type="DATA_GENERATOR"
type="SPREADSHEET_READER"

type="FLAT_FILE_WRITER"
type="DATABASE_WRITER"
type="POSTGRESQL_DATA_WRITER"
type="TRASH"

type="EXT_SORT"
type="EXT_FILTER"
type="SIMPLE_GATHER"
type="SIMPLE_COPY"
type="MAP"
type="ROLLUP"

type="HASH_JOIN"
type="MERGE_JOIN"
type="CROSS_JOIN"

Атрибуты элемента Edge

АтрибутОбязательныйОписаниеВозможные значения
idдаУникальное название ребра в пределах графа.id="edge0"
fromNodeнетИмя исходного компонента с указанием порта.fromNode="test_join:0"
toNodeнетИмя конечного компонента с указанием порта.toNode="FlatFileWriter1:0"
batchнетОбъём данных, передаваемых ребром, в Мб.batch="1024"
metaдаИдентификатор метаданных, назначаемых данному ребру.meta="metaname"

В следующих главах более подробно рассмотрено устройство графов и описано взаимодействие с ними.

Шаги

Шаг – это компонент задания с определёнными значениями атрибутов, выполняющий конкретную функцию в рамках задания. Этот минимальный алгоритм обработки данных может исполнять функцию чтения, копирования, очистки, объединения данных и т.д.

Каждый Шаг должен обязательно иметь идентификатор id для указания в разных частях здания и тип Шага type для определения того, что должен сделать этот Шаг и какие параметры ему нужно подать на вход.

Строка с объявлением Шага для чтения данных из файла будет выглядеть следующим образом:

<Node id="reader" guiX="50" guiY="100" guiName="FlatFileReader" fileURL="${READ_DIR}" type="FlatFileReader"/>

Помимо обязательных идентификатора id и типа type, для этого Шага задан путь к файлу fileURL (обязательный атрибут для Шагов чтения и записи) и указаны координаты верхней левой точки guiX и guiY, а также имя Шага guiName для отображения в Инспекторе задач и рабочей области Дизайнера.

Отображение Шага FlatFileReader в рабочей области Дизайнера

Отображение Шага FlatFileReader в рабочей области Дизайнера

Типы Шагов

Все компоненты делятся на несколько групп:

  • Для чтения - Шаги для чтения обычно являются начальными компонентами графов. Они итают данные из входных файлов,подключенных входных портов либо генерируют данные по заданному шаблону.
  • Для записи - Шаги для записи обычно ставятся в конце графа. Они могут записать даннные в файлы или базу данных, передать на выходной порт либо прервать передачу даных.
  • Некоторые Шаги используются для трансформации данных. Еще они называются преобразователями, так как могут изменять данные в соответствии с заложенным в них алгоритмом. Преобразователи получают данные и могут копировать их на все выходные порты, удалять дубликаты, фильтровать, сортироватьт, отправлять обработанные данные на один или нескольо выходных портов.
  • Объединители получают данные из двух или более источников, объединяют их в соответствии с указанным ключом и отправляют объединенные данные через выходные порты.
  • Шаги для управления ходом заданий.
  • Шаги, которые не входят в вышеописанные группы объединены в группу Другие.

Порты

Порт Шага - это точка входа или выхода данных из Шага. У каждого Шага есть хотя бы один порт - входной или выходной. Портов одного вида также может быть несколько. К примеру, у Copy может быть несколько выходных портов.

Метаданные

Все компоненты требуют, чтобы метаданные в их портах имели определенную структуру.

Чтобы создать новые метаданные, откройте редактор метаданных из панели Структуры задания, а затем внесите имя и тип новых метаданных.

Общие свойства шагов

Каждый шаг можно настроить с помощью Редактора шага.

Среди свойств, которые можно установить в этом диалоговом окне, более подробно описаны следующие:

Именование шагов

Каждый шаг имеет метку, которую можно изменить. Поскольку в графе может быть несколько шагов одного вида, вы можете назвать их предпочитаемым образом для удобства использования.

Вы можете переименовать любой шаг на вкладке Source, исправив атрибут guiName, и затем использовать обращение к шагу по этому атрибуту.

Фазы

Каждый граф можно разделить на несколько фаз, задав номера фаз в редакторе шага. Номер фазы выводится в верхнем левом углу каждого шага.

Смысл деления графа на фазы в том, что каждый граф выполняется параллельно в пределах одной фазы; т. е. все шаги, имеющие одинаковый номер фазы, и входящие в них рёбра работают одновременно. Если процесс останавливается на какой-то фазе, более высокие фазы не начинаются. Только после того, как все процессы в рамках одной фазы успешно завершатся, начётся следующая фаза.

Вот почему фазы должны оставаться неизменными во время работы графа. Номер следующей фазы графа всегда больше, чем номер предыдущей.

Таким образом, когда вы увеличиваете номер фазы на любом из шагов графа, принадлежащей одной фазе, все шаги с тем же номером фазы (но не шаги с более высокими номерами фаз), лежащие дальше по графу, автоматически меняют свою фазу на это новое значение.

Используйте редактор шага для настройки фазы, либо воспользуйтесь окошком на шаге прямо в Рабочей области:

Установка фазы шага

Установка фазы шага

Заметка: При назначении фаз внутри графа, можно указывать номер фазы с приращением больше, чем на 1 (например, 5, 10, 15…​). Таким образом, позже вы сможете добавлять новые фазы между уже существующими фазами без необходимости корректировки номерации всех фаз.

Рёбра

Если в задании есть хотя бы два шага, их можно соединить ребром. Данные будут передаваться от одного шага к другому через это ребро. По этой причине каждому ребру должны быть назначены некоторые метаданные, описывающие структуру записей данных, проходящих через ребро.

При создании ребра в графе, его концы всегда связывают исходящий порт одного шага с входящим портом другого шага. Количество портов одних шагов строго задано, а другие имеют неограниченное количество портов. Если количество портов не ограничено, новый порт создается путем подключения нового ребра.

При описании ребра используется тег <Edge> и указываются обязательные атрибуты ребра, такие как имя ребра, начальный и конечный порты соединяемых шагов, имя метаданных.


<Edge id="edge1" fromNode="reader:0" toNode="writer:0" metadata="ObjectWithPos" batchSize="1024" bufferSize="256"/>

Атрибуты ребра:

АтрибутОбязательныйОписаниеЗначение
idдаимя ребраid="FlatFileReader --> Map"
fromNode (Output port Id)даначальный портfromNode="FlatFileReader0:0"
toNode (Input port id)даконечный портtoNode="Map0:0"
bufferSizeнетРазмер выделенного для ребра буфера в памяти, измеряется в количестве записей.bufferSize="256"
metadataдаимя метаданныхmetadata="user_attrs"

Соединение компонентов ребром

Соединение компонентов ребром

Метаданные

Метаданные — это данные, описывающие структуру данных. Каждое ребро графа несет некоторые данные. Эти данные должны быть описаны с использованием метаданных. Метаданные описывают как запись в целом, так и все ее поля.

Записи могут быть разных типов, каждое поле может иметь разный тип данных.

Метаданные могут быть как внутренними, так и внешними (общими). Метаданные указываются в файле задания или в файле параметров. Метаданные также могут быть созданы динамически на основе SQL-запроса или считываться из удаленных источников.

Подробную информацию о распространении метаданных смотрите в разделе "Автоматически распространяемые метаданные".

Редактор метаданных описан в разделе "Создание-и-присвоение-метаданных-ребру".

Подробную информацию об изменении или определении разделителей в записях с разделителями или смешанных типах читайте в разделе "Определение и изменение разделителей".

Содержание главы:

Поля и записи

Запись можно рассматривать как строку файла данных или как строку таблицы базы данных. Запись состоит из полей. Каждое поле может иметь разный тип данных.

В записи каждые два соседних поля отделяются друг от друга разделителем полей, и вся запись также завершается разделителем записи. По умолчанию в системе OneBridge разделителем полей является запятая, а разделителем записей – символ переноса строки, то есть стандартная запись в файл будет произведена в таком виде:

<поле>,<поле>
<поле>,<поле>

Каждая запись относится к одному из следующих трех типов:

  • C разделителями. В записи с разделителями каждые два соседних поля отделяются друг от друга разделителем, и вся запись также заканчивается разделителем записи.

  • Фиксированной длины. В записи фиксированной длины каждое поле имеет определенную длину (размер). Длина измеряется в количестве символов.

  • Смешанный. В смешанной записи каждое поле может быть отделено друг от друга разделителем, а также иметь определенную длину (размер). Размер рассчитывается в количестве символов. Этот тип записи представляет собой смесь обоих типов, описанных выше. Каждое отдельное поле может иметь разные свойства. Некоторые поля могут иметь только разделитель, другие могут иметь указанный размер, остальные могут иметь как разделитель, так и размер.

Типы данных в метаданных

Каждое поле метаданных может иметь разный тип. В системе определены следующие типы данных:

ТипОписаниеПример
booleanЛогическое значениеtrue/false
dateДата в указанном формате (format="%d.%m.%Y %H:%M:%S"). Подробнее о способах задать формат даты описано в главе "Формат даты и времени"01.01.2025 17:43:12
integerЦелые числа42
number64-битный тип с плавающей запятой0.0078125
decimal96-битный тип (десятичная дробь)-34.6523
stringСтрока хранит набор символов в кодировке UTF-8«это пример значения поля с типом string»

Типы метаданных

Внутренние метаданные

Внутренние метаданные являются частью графа, они содержатся в файле задания и их можно увидеть на вкладке Источник.

Создание внутренних метаданных

Внутренние метаданные могут быть созданы следующим способом:

На панели Outline вы можете выбрать элемент Metadata правой кнопкой мыши и выбрать New metadata в контекстном меню.

Редактор метаданных

Редактор метаданных

Внешние метаданные

Внешние (общие) метаданные располагаются в отдельном файле и могут использоваться несколькими графами.

Создание внешних метаданных

Для создания внешних метаданных, выберите в контекстном меню папки, в которую хотите поместить файл метаданных, пункт New file. Задайте название и расширение .fmt для этого файла.

Затем откройте созданный файл в рабочей области и задайте его содержимое на вкладке Source.

Указание метаданных во внешнем фйле

Указание метаданных во внешнем фйле

Связывание внешних метаданных

После создания внешние метаданные должны быть связаны с каждым графом, в котором они будут использоваться. Для этого нужно щелкнуть правой кнопкой мыши группу Метаданные на панели Outline и выбрать Link metadata в контекстном меню. После этого откроется редактор матаданных, в который нужно ввести путь до файла с метаданными. Путь указывается относительно проекта.

Линкование метаданных в редакторе

Линкование метаданных в редакторе

Передача метаданных между компонентами графа

В данный момент реализовано назначение метаданных вручную каждому ребру. Это можно сделать двумя способами:

  • Откройте редактор ребра двойным щелчком по имени ребра. Выберите имя метаданных в выпадающем списке, сохраните изменения, нажав Save.
  • Другой способ назначить метаданные - методом drag-and-drop, зажав ctrl и перетащив нужные метаданные с панели Outline на ребро.

Создание метаданных

Создание метаданных возможно либо через указание в файле задания, либо в редакторе метаданных в Дизайнере.

Указание метаданных в источнике

Указание в источнике производится вручную в заголовке файла, в теге Metadata. Создайте внутри тег Record, задайте значение параметра name и укажите значения атрибутов для Field.

Указание метаданных в источнике

Указание метаданных в источнике

Создание метаданных в редакторе

Для создания метаданных в редакторе, откройте его из панели Outline из конекстного меню Metadata -> New metadata. Задайте имя записи, задайте имена полей метаданных, резделители полей и строк, укажите тип данных для каждого поля. Сохраните изменения кнопкой Save.

Создание метаданных в редакторе

Создание метаданных в редакторе

Подробнее использование редактора метаданных описано в разделе Дизайнер заданий.

Формат даты и времени

Форматирование описывает, как значения даты/времени должны считываться и записываться из/в строковое представление. На форматирование и синтаксический анализ дат также влияют локаль и часовой пояс.

На данный момент пересчет времени в зависимости от локального отключен, используется только серверное время в UTC. То есть если вы хотите установить расписание на 12:35 по локальному времени и для вашего местоположения акутально UTC+3ч, время выполнения расписания следует указать 09:35.

В OneBridge используется указание префикса для форматирования данных. Доступны два встроенных механизма обработки данных: стандартный для языка Rust модуль (описан в таблицах ниже) и международный формат ISO 8601 (https://en.wikipedia.org/wiki/ISO_8601).

Следующие спецификаторы доступны как для форматирования, так и для синтаксического анализа.

Для указания даты:

СпецификаторПримерОписание
%Y2001

Полный год пролептического1 григорианского календаря, дополненный нулями до 4 цифр. Поддерживаются годы от -262144 до 262143. Годы до 1 г. до н.э. или после 9999 г. н.э. требуют начального знака (+/-).

%C20

Год, разделенный на 100, дополненный нулями до 2 цифр2.

%y01

Год, по модулю 100, дополненный нулями до 2 цифр2.

%m07Номер месяца (01–12), дополненный нулями до 2 цифр.
%bJulСокращенное название месяца. Всегда 3 буквы.
%BJulyПолное название месяца. Также принимает соответствующую аббревиатуру при парсинге данных.
%hJulТо же, что %b
%d08Номер дня (01–31), дополненный нулями до 2 цифр.
%e 8То же, что %d, но дополнено пробелами.
%aSunСокращенное название дня недели. Всегда 3 буквы.
%ASundayПолное название дня недели. Также принимает соответствующую аббревиатуру при парсинге.
%w0Числовое обозначение дня недели. Sunday = 0, Monday = 1, …, Saturday = 6.
%u7Числовое обозначение дня недели. Monday = 1, Tuesday = 2, …, Sunday = 7. (ISO 8601)
%U28

Номер недели, начинающийся с воскресенья (00–53), дополненный нулями до 2 цифр3.

%W27То же, что и %U, но неделя 1 начинается с первого понедельника этого года.
%G2001

То же, что %Y, но использует номер года в недельном календаре ISO 86014.

%g01

То же, что %y, но использует номер года в недельном календаре ISO 86014.

%V27

То же, что и %U, но использует номер недели в недельном календаре ISO 8601 (01–53)4.

%j256День года (001–366), дополненный нулями до 3 цифр.
%D07/08/01Формат `месяц-день-год`. То же, что %m/%d/%y.
%x07/08/01Представление даты в локали (например, 31.12.99).
%F2001-07-08Формат `год-месяц-день` (ISO 8601). То же, что %Y-%m-%d.
%v8-Jul-2001Формат `день-месяц-год`. То же, что %e-%b-%Y.
1

Пролептический григорианский календарь (предваряющий григорианский календарь, от др.-греч. πρόληψις «предвосхищение») — календарь, расширяющий григорианский календарь на период до его введения 15 октября 1582 года.

2

%C, %y разделяют года по группам, поэтому для 100 г. до н.э. (номер года -99) будут напечатаны -1 и 99 соответственно.

3

%U: Неделя 1 начинается с первого воскресенья этого года. Неделя 0 может быть указана за несколько дней до первого воскресенья.

4

%G, %g, %V: неделя 1 — это первая неделя, в которой в этом году содержится не менее 4 дней. Недели 0 не существует, поэтому ее следует использовать с %G или %g.

Для указания времени:

СпецификаторПримерОписание
%H00Количество часов (00–23), дополненное нулями до 2 цифр.
%k 0То же, что %H, но дополнено пробелами. То же, что %_H.
%I12Количество часов в 12-часовом формате (01–12), дополненное нулями до 2 цифр.
%l12То же, что %I, но дополнено пробелами. То же, что %_I.
%Pamam или pm в 12-часовом формате.
%pAMAM или PM в 12-часовом формате.
%M34Количество минут (00–59), дополненное нулями до 2 цифр.
%S60

Количество секунд (00–60), дополненное нулями до двух цифр5.

%f

26490000

Количество наносекунд с последней целой секунды6.
%.f

.026490

Доля секунды. Съедает ведущую точку6.
%.3f.026Доля секунды с фиксированной длиной 3.
%.6f.026490Доля секунды с фиксированной длиной 6.
%.9f.026490000Доля секунды с фиксированной длиной 9.
%3f026Доля секунды, как %.3f, но без начальной точки.
%6f026490Доля секунды, как %.6f, но без начальной точки.
%9f026490000Доля секунды, как %.9f, но без начальной точки.
%R00:34Формат `час-минута`. То же, что %H:%M.
%T00:34:60Формат `час-минута-секунда`. То же, что %H:%M:%S.
%X00:34:60Представление местного времени (например, 23:13:48).
%r12:34:60 AM12-часовое местное время. (например, 23:11:04). Возвращает %X, если языковой стандарт не поддерживает 12-часовой формат времени.
5

%S: учитываются дополнительные секунды, поэтому возможно 60.

6

%f, %.f:
%f и %.f — это совершенно разные спецификаторы форматирования.
%f подсчитывает количество наносекунд, прошедших с последней целой секунды, а %.f — доли секунды. Пример: 7 мкс форматируется как 7000 с %f и форматируется как .000007 с %.f.

Для указания часового пояса:

СпецификаторПримерОписание
%ZACST

Название местного часового пояса. Пропускает все символы без пробелов во время парсинга. Идентичен %:z при форматировании7.

%z+0930Смещение местного времени по отношению к UTC (при этом UTC равно +0000).
%:z+09:30То же, что %z, но с двоеточием.
%::z+09:30:00Смещение от местного времени до UTC в секундах.
%:::z+09Смещение от местного времени до UTC без учета минут.
%#z+09Только при парсинге: то же, что и %z, но позволяет использовать или не использовать минуты.
7

%Z: поскольку встроенный модуль не знает часовых поясов за пределами их смещений, этот спецификатор печатает смещение только при использовании для форматирования. Аббревиатура часового пояса НЕ будет напечатана.
Смещение не будет заполнено из проанализированных данных и не будет проверено. Часовой пояс полностью игнорируется.
Невозможно надежно преобразовать аббревиатуру в смещение, например, CDT может означать либо центральное летнее время (Северная Америка), либо летнее время Китая.

Для указания даты и времени:

СпецификаторПримерОписание
%cSun Jul 8 00:34:60 2001Дата и время региона (например, четверг, 3 марта, 23:05:25 2005 г.).
%+2001-07-08T00:34:60.026490+09:30

Формат даты и времени ISO 8601/RFC 33398.

%s994518299

Временная метка UNIX, количество секунд, прошедших с 01.01.1970 00:00 UTC9.

8

%+: То же, что %Y-%m-%dT%H:%M:%S%.f%:z, т. е. 0, 3, 6 или 9 дробных цифр для секунд после двоеточия в смещении часового пояса.
Этот формат также поддерживает использование Z или UTC вместо %:z. Они эквивалентны +00:00.
Обратите внимание, что все T, Z и UTC анализируются без учета регистра.
Типичные реализации функции для преобразования даты и времени имеют разные (и зависящие от локали) форматы этого спецификатора. Лучше избегать этого спецификатора, если вы хотите точно контролировать результат.

9

%s: значение может быть отрицательным. Учитываются только невисокосные секунды.

Специальные спецификаторы:

СпецификаторПримерОписание
%tЗнак табуляции (\t).
%nЗнак перевода строки (\n).
%%Знак процента.

Разделители

Разделители определяют правила, по которым будут прочитаны данные из файла шагом FlatFileReader и по которым будет произведена запись в файл в результате работы шага FlatFileWriter.

В системе существует два типа разделителей:

  • разделители полей fieldDelimiter;
  • разделители записей recordDelimiter.

Разделители назначаются при определении метаданных в теге <Record> и могут быть переопределены в атрибутах шагов.

По умолчанию, разделителем записей является символ перевода строки «\n», а разделителем полей – запятая «,».

Для чтения файла такого вида: qwe|rty|uio;asd|fgh|jkl;zxc|vbn|mko в качестве разделителя полей следует задать вертикальную линию, а в качестве разделителя записей – точку с запятой: <Record fieldDelimiter="|" recordDelimiter=";">.

Если назначить метаданные для записи, установив разделитель полей <Record fieldDelimiter="_">, а разделитель записей не задать, то выходной файл будет выглядеть таким образом:

qwe_rty_uio
asd_fgh_jkl
zxc_vbn_mko

RecordDelimiter при этом будет по умолчанию равен символу переноса строки.

Во FlatFileReader и FlatFileWriter можно переопределять fieldDelimiter и recordDelimiter в атрибутах шага. Тогда, даже если в метаданных в элементе <Record> указаны одни разделители – в шагах для чтения или записи могут быть указаны другие разделители, переопределённые значения будут приоритетными при выполнении алгоритма.

Непечатаемые разделители

Если нужно использовать любой непечатаемый разделитель, вы можете записать его как выражение. Например, вы можете ввести следующую последовательность символов в качестве разделителя записей в метаданных: RecordDelimeter=\u0014.

Такие выражения состоят из кода Unicode \uxxxx без кавычек. Обратите внимание, что каждый символ обратной косой черты «\», содержащийся во входных данных, на самом деле будет дублироваться при просмотре. Таким образом, вы увидите «\» в своих метаданных.

Соединения с базами данных

Соединение с базой данных позволяет получить доступ к источникам данных в виде различных баз данных. При подключении к базе вы можете считывать данные из таблиц, выполнять SQL-запросы или вставлять записи в таблицы базы данных. Эти действия выполняются шагами, использующими соединение с базой данных.

Существует два способа доступа к базе данных:

  • использование клиента на компьютере, который подключается к базе данных, расположенной на сервере, с помощью клиентской утилиты. Этот подход используется в массовых загрузчиках;
  • использование драйвера ODBC. Для каждого подключения к базе данных требуется драйвер ODBC. Драйверы устанавливаются отдельно и не включены в OneBridge.

В OneBridge есть два вида подключения к базам - внутреннний и внешний.

  • Внутренние соединения с базой данных являются частью графа, их описание можно увидеть в xml-представлении графа. При внутреннем типе соединения все параметры подключения задаются в файле и могут быть использованы только этим графом.

  • Внешним соединением могут пользоваться другие графы. Оно задаётся в отдельном файле с расширением .con и в графе указывается только ссылка на файл соединения.

Создание подключения

Пример создания подключения приведён в главе Установка соединения с базой данных.

Чтобы создать подключение, щелкните правой кнопкой мыши Connections на панели Outline и выберите:

  • New connection - для создания внутреннего подключения
  • Link connection - для указания ссылки на внешний файл с описанием подключения.

Для внутреннего подключения к базе нужно указать имя и параметры соединения:

  • Для внутреннего соединения нужно заполнить атрибут URL по шаблону, актуальному для конкретной базы. Шаблон указывается при выборе способа соединения в редакторе соединений.
  • Для внешнего соединения достаточно указать путь к файлу с конфигурацией в атрибуте dbConfig.

Для передачи паролей стоит использовать защищенные параметры.

Значения параметров можно указать следующим образом в файле задания либо в файле конфигурации:


<GraphParameters>

<!--тип соединения с базой данных-->
<GraphParameter name="CONN_TYPE" value="postgresql"/>

<!--имя пользователя в базе-->
<GraphParameter name="USER" value="user1"/>

<!--пароль пользователя в базе-->
<GraphParameter name="PASSWORD" value="pass"/>

<!--хост-->
<GraphParameter name="HOST" value="10.1.1.4"/>

<!--порт базы данных-->
<GraphParameter name="PORT" value="5432"/>

<!--имя базы данных-->
<GraphParameter name="DATABASE" value="MyDB"/>

</GraphParameters>

Типы соединения с базами данных

На данный момент подключены следующие нативные соединения с базами данных:

Тип соединения в OneBridgeБазаШаблон строки подключения
postgresPostgreSQL
postgres://user:password@localhost:port/database
oracleOracle
oracle:user/password@localhost:port/database
sqlserverMicrosoft SQL Server
sqlserver:server=tcp:localhost,port;user=user;password=password

Подключение других баз возможно по запросу пользователя.

Через ODBC доступна работа со следующими базами:

  • PostgreSQL,
  • Oracle,
  • MSSQL,
  • SQLite,
  • Firebird

Для подключения через ODBC необходимо изменить строку подключения, добавив в начале строки odbc@. Например, для подключения к Firebird, строку подключения можно составить так: odbc@firebird:Driver={Firebird};User=SYSDBA;Password=2wsx2WSX;Database=sbar-dev-db03.sbar.local/3050:/opt/firebird/data/onebrige-dev.fdb.

Параметры

Параметры аналогичны константам, которые можно определить один раз и использовать в различных местах конфигурации задания.

Значения параметров графа всегда конвертируются в строку. Каждое значение, номер, путь, имя файла, атрибут и т. д. можно настроить или изменить с помощью параметров.

Основными преимуществами параметров являются возможность использовать шаблон для указания параметра и изменять его значение только в одном месте. Для подстановки значения параметра используйте шаблон "${PARAMETER_NAME}.

Параметры создаются с помощью редактора параметров или указываются в файле параметров, на который дается ссылка в графе. Подробнее про разные параметры на странице "Внутренние и внешние параметры".

Внутренние и внешние

Параметры могут быть

  • внутренними – указываются непосредственно в файле задания;
  • внешними – указываются в отдельном файле и подключаются с помощью элемента <GraphParameterFile>.

Внутренние параметры указываются в графе, в редакторе параметров. Они отображаются на панели Outline и их можно увидеть на вкладке Source. Внутренние параметры полезны для параметризации в рамках одного графа.

Внешние (общие) параметры хранятся вне графа в отдельном файле с расширением .prm в папке проекта. Использование внешних параметров подходят для параметров, используемых несколькими графами.

Чтобы подключить в файл задания внешние параметры, укажите путь к файлу в редакторе линкованных параметров в поле fileURL.

Защищенные параметры

Обычные параметры графа сохраняются либо в файлах .grf (внутренние параметры), либо в файлах .prm (внешние параметры). Это означает, что значения параметров вашего графа хранятся в обычных xml-файлах. Такое поведение абсолютно корректно для большинства вариантов использования параметров графа. Но иногда параметр графа может представлять конфиденциальную информацию, которую не следует сохранять в текстовом файле в файловой системе, например, пароль к базе данных. Для этой цели OneBridge предоставляет функцию безопасных параметров.

Для использования безопасных параметров установите чекбокс напротив значения параметра в редакторе параметров. После ввода значения оно будет отображаться в защищённом виде и чтобы изменить его - нужно будет ввести его заново и сохранить изменения. Расшифровка защищенного параметра выполняется автоматически во время выполнения задания.

Словарь

Словарь — это объект для хранения данных, связанный с каждым запуском графа в OneBridge. Его цель — обеспечить простое и типобезопасное хранение различных параметров, требуемых графом.

Он не ограничивается хранением только входных или выходных параметров, но также может использоваться как способ обмена данными между различными компонентами одного графа.

Когда граф загружается из своего определения в XML файле, словарь инициализируется на основе его определения в спецификации графа. Каждое значение инициализируется значением по умолчанию, если оно установлено, либо дефолтным для типа значением.

Между двумя последующими запусками любого графа словарь сбрасывается до исходных настроек или настроек по умолчанию, так что все изменения словаря после выполнения графа уничтожаются. По этой причине словарь нельзя использовать для передачи значений между разными прогонами одного и того же графа.

Создание словаря описано в главе Добавление словаря в описании Дизайнера.

Работа со словарём для передачи значений во внутренний граф при использовании шага ExecuteGraph описана в примере передачи параметров через словарь.

Преобразования

Преобразование — это фрагмент кода, который определяет, как входные данные преобразуются в выходные данные при прохождении через шаг. Преобразование определяется в атрибуте "transform" или "normalize".

Определение преобразования задается вручную в файле задания с помощью языка JavaScript.

Шаги, допускающие преобразования

Преобразователи можно использовать в таких шагах как HashJoin, MergeJoin, Map, Rollup. В этих шагах есть возможность задать алгоритм преобразования на своё усмотрение, в то время как для других шагов алгоритмы обработки данных чётко определены.

Возвращаемые значения преобразователей

Ниже в таблице представлены все возможные варианты возвращаемых преобразователями значений.

ЗначениеОписаниеПример использования
ALLВ этом случае запись отправляется на все выходные порты.
...
return ALL;
SKIPСообщает что мы пропускаем данный выход (пропускаем цикл преобразования)
...
else {
    ...
    return SKIP;
    }

Любое целое число больше или равное 0Запись отправляется на выходной порт, номер которого равен этому возвращаемому значению.
  • return [1, 4, 9] – вернет запись на 1-ый, 4-ый и 9-ый порт

  • return [ERROR: 2, 4, 5, 7] – сообщает, что произошли ошибки с номерами 2, 4, 5 и 7

Методы преобразования данных

В некоторых шагах можно самостоятельно определить алгоритм обработки данных. К таким шагам относятся HashJoin, MergeJoin, HashJoin, Map, Rollup. Пользовательский алгоритм преобразования в этих шагах определяется в атрибуте с именем "transform" с помощью JavaScript:

<Node id="m" type="Map">
    <Attr name="transform">
        <![CDATA[
            function transform() {
            //transform code
            $out[0].field1 = $in[0].field1 * 3,14;
            $out[0].field2 = $in[1].field2 + 'success_string';

            return ALL;
            }
        ]]>
    </Attr>
</Node>

В шагах, использующих функцию преобразования, можно применять методы для работы с записями, описанные в примере ниже:

<Node id="map" guiX="250" guiY="100" guiName="map" type="Map">
    <Attr name="transform"><![CDATA[
        $out[0].person = $in[0].name.toString() + "_" + $in[0].surname.toString();
        $out[1].person = $in[0].name.toString().toUpperCase() + " " + $in[0].surname.toString().toUpperCase();
        
        return ALL;

Param(param_name) возвращает значение param_name, но выдает ошибку unknown parameter 'param_name', если имя параметра не определено

                0 => $out[0].obj_type = param("X"),
                1 => $out[0].obj_type = param("RbISb"),
                2 => $out[0].obj_type = format!("secure number is {}", param("FILE_PRM_NUM")),

Param_or(param_name, default_value) возвращает значение параметра или default_value, если параметра нет


                3 => $out[0].obj_type = input.obj_type + " is not " + &param_or("XX", "goose") + "!",

Try_param(param_name) возвращает Some(value) (value является строкой) в случае, если параметр есть, None, если параметра нет


                4 => $out[0].obj_type = if let Some(obj_type) = try_param("X") { obj_type } else { "tuturu".to_string() },

Param_parse_or(param_name, default_value) возвращает преобразованное значение параметра, если он есть или default_value. Возвращает ошибку, если значение параметра не преобразуется к типу

                5 | 6 => {
                    $out[0].y_coord = param_parse_or("X", 24);
                    $out[0].obj_type = param_parse_or("X", "tururu".to_string());
                }
                 _ => $out[0].obj_type = input.obj_type,
            
                index += 1;

                return ALL;

Хеш-таблицы

Хеш-таблица (lookup table) — это структура данных, которая обеспечивает быстрый доступ к данным, хранящимся с использованием ключа. Она позволяет уменьшить частоту обращений к базе данных или файлам.

По умолчанию хеш-таблица позволяет хранить несколько записей с одинаковым значением ключа. Если для вашего кейса это некорректно, можно запретить хранить дублирующиеся значения, тогда будет сохранено последнее записанное значение.

Все записи такой таблицы находятся в памяти во время работы графа. Поэтому на сервере должно быть достаточно памяти для хранения всех записей из используемой таблицы. Содержимое таблицы можно записать в файл и сохранить в проекте, чтобы использовать её содержимое через время в других графах.

Заметка: В редкторе содержимого используйте обращение к хеш-таблицам через конструкцию lookupTables.<tableName>.<lookupMethod>(<arguments>); в коде атрибута transform в шагах, разрешающих пользовательские преобразования, например, DATA_GENERATOR и MAP.

Создание lookup таблицы

Чтобы создать хеш-таблицу, сначала нужно её определить в графе, а затем вставить в неё значения с помощью метода insert. В дизайнере для создания таблицы используйте панель Outline и редактор lookup таблиц, аналогично созданию метаданных и параметров. В веб интерфейсе OneBridge таблицу можно определить на странице Проекты в редакторе содержимого файла с помощью тега <LookupTable> и его атрибутов, описанных в таблице ниже.

Атрибуты lookup таблиц:

АтрибутОбязательныйОписаниеВозможные значения
nameдаУникальное имя таблицы.name="lt2"
fileнетПуть до файла с данными таблицы. Если файла не существует, то он будет создан, но папка, в которой этот файл должен лежать, должна существовать. Если путь до файла не указан, то таблица будет жить только в памяти в течении работы графа.file="onebridge-dev/projects/ready-check/lookupExample1"
metadataдаСхема данных.metadata="metadataName1"
keyдаКлюч формата fieldname1;fieldname2;...;fieldnameN.key="person;date"
keyDuplicatesдаЧекбокс. Показывает, разрешается ли хранить в таблице больше одной записи с одинаковым значением ключа, по умолчанию keyDuplicates="true".keyDuplicates="false"

Так может выглядеть определение таблицы в файле графа:


<Graph>
    <Global>
    ...
        <LookupTable id="lookup_table1" key="num;date" metadata="meta1" name="lt1" file="lt1_file" keyDuplicates="false"/>
    </Global>

Методы lookup таблиц:

МетодОписаниеПример использования
getВозвращает одну запись по ключу. Ключ это массив значений полей.
//из таблицы lt1 будет прочитана запись со значением ключа = i
let got = lookupTables.lt1.get([i]); 
insertВставляет запись.
//в таблицу lt1 будет добавлена запись
lookupTables.lt1.insert({ foo: i + 1 }); 
removeУдаляет запись по ключу аналогично get.
//из таблицы lt1 будут удалены записи с ключом i
lookupTables.lt1.remove([i]); 
numKeysВозвращает количество уникальных ключей в таблице, аргументов нет.
//переменной num будет присвоено значение, отражающее количество уникальных ключей в таблице lt1
function generate() {
    let num = lookupTables.lt1.numKeys(); 
    $out[0].foo = num;

    return ALL;
}
clearОчищает таблицу, аргументов нет.
//таблица lt1 будет очищена от значений (её структура останется такой, как была задана при создании)
lookupTables.lt1.clear(); 

Правила использования lookup таблиц

Для корректной работы с таблицами такого типа, нужно соблюдать правила их использования:

  1. В начале работы графа он считывает содержимое хеш-таблицы и далее работает с ним в памяти. Запись в таблицу происходит в конце фазы, в которой производится обращение к таблице.

  2. Необходимо избегать использования шагов для чтения таблиц и записи в таблицу в рамках одной фазы.

На данный момент алгоритм таков, что при попытке использовать сочетание шагов для чтения и записи в лукап таблицу в одной фазе результат работы графа будет некорректен.

В одной фазе можно:

  • Использовать несколько LOOKUP_TABLE_READER для чтения из таблицы А.
  • Использовать несколько LOOKUP_TABLE_READER для чтения из разных таблиц А, B, C.
  • Использовать один LOOKUP_TABLE_WRITER для записи в таблицу А.
  • Производить чтение и запись в таблицу А, но только внутри пользовательского кода шага, с помощью методов get и insert.

В одной фазе нельзя:

  • Обращаться к таблице А из шагов для чтения и записи (LOOKUP_TABLE_READER и LOOKUP_TABLE_WRITER).
  • Использовать несколько LOOKUP_TABLE_WRITER для записи в таблицу А.
  • Обращаться к таблице А из разных шагов с пользовательским кодом.

Пример использования отдельных шагов для чтения и записи:

<Graph>
    <Global>
        <Metadata id="meta">
            <Record>
                <Field name="foo" type="integer" />
            </Record>
        </Metadata>
        <LookupTable id="lookup_table1" key="foo" metadata="meta" name="lt1" file="1170_lt1" />
    </Global>
    <Phase number="0">
        <!-- This shows how to insert records into lookup tables with built-in node -->
        <Node id="datagen1" type="DATA_GENERATOR" recordsNumber="4">
            <attr name="generate">
                <![CDATA[
                let i = 0;

                function generate() {
                    $out[0].foo = i;
                    i++;

                    return ALL;
                }
                ]]>
            </attr>
        </Node>
        <Node id="ltwriter" type="LOOKUP_TABLE_WRITER" lookupTableName="lt1" />
        <Edge id="edge1" fromNode="datagen1:0" toNode="ltwriter:0" metadata="meta" />
    </Phase>
    <Phase number="1">
        <!-- This shows how to read all records from lookup tables with built-in node -->
        <Node id="ltreader" type="LOOKUP_TABLE_READER" lookupTableName="lt1" />
        <Node id="trash2" type="TRASH" debugOutput="false" />
        <Edge id="edge2" fromNode="ltreader:0" toNode="trash2:0" metadata="meta" />
    </Phase>
</Graph>

Пример обращения к таблице из шага с пользовательским кодом:

<Graph>
    <Global>
        <Metadata id="meta">
            <Record>
                <Field name="foo" type="integer" />
            </Record>
        </Metadata>
        <LookupTable id="lookup_table1" key="foo" metadata="meta" name="lt1" file="1170_lt1" />
    </Global>
    <Phase number="0">
        <!-- This shows how to insert and retrieve records to/from lookup tables in user code -->
        <Node id="datagen" type="DATA_GENERATOR" recordsNumber="4" enabled="false">
            <attr name="generate">
                <![CDATA[
                let i = 0;

                function generate() {
                    let got = lookupTables.lt1.get([i]);
                    let foo = got ? got.foo : null;
                    $out[0].foo = foo;

                    lookupTables.lt1.insert({ foo: i + 1 });
                    i++;

                    return ALL;
                }
                ]]>
            </attr>
        </Node>
        <Node id="trash" type="TRASH" debugOutput="true" />
        <Edge id="edge" fromNode="datagen:0" toNode="trash:0" metadata="meta" />
    </Phase>
</Graph>

Объединение lookup таблиц

Объединение хеш-таблиц возможно с помощью шагов MAP и NORMALIZER.

  • MAP стоит использовать, если 1 запись мастер-потока объединяется с 1 записью слейв-потока.
  • NORMALIZER стоит использовать, если записей для объединения на слейв-потоке больше, чем 1.

Пример объединения lookup таблиц с помощью MAP:

<Graph>
    <Global>
        <Metadata id="meta1">
            <Record>
                <Field name="n" type="integer"/>
                <Field name="s" type="string"/>
            </Record>
        </Metadata>
        <Metadata id="meta2">
            <Record>
                <Field name="n" type="integer"/>
                <Field name="b" type="boolean"/>
            </Record>
        </Metadata>
        <Metadata id="meta3">
            <Record>
                <Field name="num" type="integer"/>
                <Field name="bool" type="boolean"/>
                <Field name="str" type="string"/>
            </Record>
        </Metadata>
        <LookupTable id="lookup_table1" key="n" metadata="meta1" name="lt1" file="1170_lt3_string" />
        <LookupTable id="lookup_table2" key="n" metadata="meta2" name="lt2" file="1170_lt4_bool" />
        <LookupTable id="lookup_table3" key="num" metadata="meta3" name="lt3" file="1170_lt5_joinmap" keyDuplicates="false"/>
    </Global>        
    <Phase number="0">
        <Node id="ltreader1" type="LOOKUP_TABLE_READER" lookupTableName="lt1" />
        <Edge id="edge3" fromNode="ltreader1:0" toNode="map:0" metadata="meta1" />
    </Phase>
    <Phase number="1">
        <Node id="map" type="MAP">
        <attr name ="transform">
              <![CDATA[
              let i = 0;

                function transform() {
let lt2 = lookupTables.lt2.get([i]);
let bool = lt2 ? lt2.b : null;
let str = lt2 ? lt2.s : null;
                    $out[0].num = $in[0].n;
                    $out[0].bool = bool;
                    $out[0].str = $in[0].s;

                    i++;

                    return ALL;
                }
                ]]>
        </attr>
        </Node>
        <Node id="trash2" type="TRASH" debugOutput="true" />
        <Edge id="edge4" fromNode="map:0" toNode="trash2:0" metadata="meta3" />
    </Phase>
</Graph>

Алгоритмы обработки данных

В этом разделе описаны запрограммированные шаги, которые пользователь может использовать для составления своего файла задания для обработки данных.

Каждый шаг представляет собой готовый алгоритм обработки данных, например, EXT_SORT – это шаг для сортировки данных.

Данные поступают в шаг через входной порт, обрабатываются согласно алгоритму и выводятся через выходной порт. Входных и выходных портов у шага может быть разное количество. Например, у СONCAT может быть несколько входов, а у TRASH не бывает выходных портов.

Шагов в задании может быть сколько угодно, но обязательно должен присутствовать шаг для чтения данных в начале алгоритма и для записи данных - в конце алгоритма. Между ними могут быть добавлены шаги для преобразования, объединения данных и другие.

Шаги в задании соединяются ребрами для передачи информации. Каждому ребру необходимо назначать метаданные для описания данных, передаваемых между шагами.

Подробное описание создания файла задания описано в главе Задания. Несколько примеров составления заданий приведены в разделе Быстрый старт.

Типы данных метаданных

Каждое поле метаданных может иметь разный тип. Для метаданных в OneBridge определены следующие типы данных:

Тип данныхОписаниеПример
booleanЛогическое значениеtrue
dateДата01.01.2025
integerЦелые числа42
numberДробные числа (числа с плавающей точкой)345.65
decimalДробные числа (числа с плавающей точкой)345.65
stringСтрока хранит набор символов в кодировке UTF-8«это пример значения поля с типом string»

Для чтения данных

Шаги для чтения (считыватели) могут считывать данные из входных файлов, получать их из подключенного дополнительного входного порта, читать из базы данных. Шаг DATA_GENERATOR занимается генерацией данных и тоже относится к этой группе, поскольку является начальным шагом.

Различают следующие шаги для чтения:

FLAT_FILE_READER

FLAT_FILE_READER считывает данные из плоских файлов в формате CSV и TXT с разделителями, фиксированной длины или смешанных текстовых файлов. Удаленные файлы доступны для чтения через протоколы FTP и SFTP.

Порты FLAT_FILE_READER:

Тип портаНомерОбязательныйОписаниеМетаданные
Output0даДля корректных записейЛюбые
Output1 (в разработке)нетДля некорректных записейСтруктура метаданных порта ошибок будет приведена в таблице ниже

Атрибуты FLAT_FILE_READER:

АтрибутОбязательныйОписаниеВозможные значения
fileURLдаПуть к источнику данных (плоский файл) для чтения. Для обращения по FTP используйте шаблон ftp://username:password@hostname:port/path-to-file${READ_DIR}/in.txt
charsetнетКодировка файла, читаемого с помощью этого шага.encoding="windows-1251"
dataPolicyнетОпределяет обработку неправильно отформатированных или неверных данных. Может принимать значения "strict", "lenient"dataPolicy="strict" по умолчанию
trimнетУказывает, следует ли удалять начальные и конечные пробелы из строк в момент прохождения данных через FLAT_FILE_READER.trim="default" по умолчанию. Возможные значения: true, false, default/

quotedStrings

нетПоля, содержащие специальные символы (запятая, новая строка или двойные кавычки), должны быть заключены в кавычки. В качестве символа кавычки принимаются только одинарные/двойные кавычки. Если установлено значение true, специальные символы не рассматриваются как разделители и удаляются при чтении компонентом.
Пример: Чтобы прочитать входные данные "25"|"Джон", установите для параметра quotedStrings значение true и установите для символа кавычки значение quoteChar="&quot;". В результате будут получены два поля: 25|Джон.
quotedStrings="false" по умолчанию

quoteChar

нетСимволы, в которые будет заключено значение поля при quotedStrings="true".quoteChar="&quot;"

fieldDelimiter

нетРазделитель полейfieldDelimiter=","

recordDelimiter

нетРазделитель записейrecordDelimiter="/n"

Обрезание данных

  1. Входные строки обрабатываются в соответствии с типом данных поля следующим образом:
  • Пробелы удаляются как из начала, так и из конца поля для типов данных boolean, date, integer.
  • Входная строка остаётся полем, включающим начальные и конечные пробелы в случае типа данных string.
  1. Если для атрибута trim установлено значение true, все начальные и конечные пробельные символы удаляются. Поле, состоящее только из пробелов, преобразуется в нулевое значение (строка нулевой длины). Значение false подразумевает сохранение всех начальных и конечных символов пробелов. Входная строка может содержать пробелы только если представляет строковый тип данных. В случае trim = "default", поведени езависит от типа обрабатываемых данных: для типа string, значение строки останется с начальными и конечными пробелами, если они были, для остальных типов - пробелы будут убраны. По умолчанию trim="default".

Пример. Чтение файла.

Например, нужно прочитать файл "customers.csv". Каждая запись в нем содержит три поля: "дата", "фамилия" и "имя", разделенные символом "|". Нужно считать этот файл для дальнейшей обработки в системе.

Данные в файле:

01.02.2011|Горилов|Алексей
29.12.2013|Нечаев|Илья
25.11.2016|Васькин|Николай
23.10.2019|Иванов|Григорий
19.09.2022|Горбунов|Евгений

Решение:

Для чтения простого файла используется шаг FLAT_FILE_READER. В редакторе шага нужно задать значение атрибута fileURL="customers.csv".

Чтобы правильно прочитать записи, нужно описать входные метаданные. В редакторе матаданных задайте имя метаданным, например, "customers_data" и создайте поля "date", "last_name" и "first_name". Установите для них типы данных "date", "string" и "string" соответственно.

С помощью атрибута format="%Y-%m-%d" можно указать используемый формат даты для поля "date".

Данные читаемые с помощью шага FLAT_FILE_READER нужно обязательно отправить дальше. Если обработка данных не требуется, можно использовать шага TRASH для остановки потока данных.

Шаги FLAT_FILE_READER и TRASH нужно соединить ребром и присвоить этому ребру созданную метадату "customers_data".

Данные из файла "customers.csv" будут считаны во внутреннюю память Onebridge:

datelast_namefirst_name
01.02.2011ГончаровАлексей
29.12.2013НечаевИлья
25.11.2016ВаськинНиколай
23.10.2019СеровГригорий
19.09.2022ГлинкаЕвгений

RAW_READER

RAW_READER считывает данные, хранящиеся во внутренних файлах формата OneBridgeFile.

Порты RAW_READER:

Тип портаНомерОбязательныйОписаниеМетаданные
Input0нетДля корректных входных записейПоля с типом данных byte/cbyte
Output0даВыходной порт для корректных данныхЛюбые
1-nнетВыходной порт для корректных данныхКак на Output 0

Атрибуты RAW_READER:

АтрибутОбязательныйОписаниеВозможные значения
fileURLдаАтрибут, определяющий, какой файл данных OneBridgeFile будет считываться

Пример. Чтение файла во внутреннем формате.

Чтобы прочитать файл ${DATAIN_DIR}/my-file.obf нужно заполнить атрибут fileURL.

АтрибутЗначение
fileURL${DATAIN_DIR}/my-file.obf

RAW_READER прочтёт все данные из этого файла.

LOOKUP_TABLE_READER

Шаг LOOKUP_TABLE_READER считывает данные из хеш-таблицы (Lookup Table).

Порты LOOKUP_TABLE_READER:

Тип портаНомерОбязательныйОписаниеМетаданные
Input0дадля записываемых в хеш-таблицу записей.Любые

Атрибуты LOOKUP_TABLE_READER:

АтрибутОбязательныйОписаниеВозможные значения
lookupTableNameдаИмя хеш-таблицы.lookupTableName="lt1"

Следующий пример графа демонстрирует чтение из хеш-таблицы с именем lookupTable001 и передачу считанных данных в треш:


<Graph>
    <Global>  
      
        <Metadata id="meta1">
            <Record>
                <Field name="n" type="integer"/>
                <Field name="s" type="string"/>
            </Record>
        </Metadata>

        <LookupTable id="lookup_table1" key="n" metadata="meta1" name="lt1" file="lookupTable001" />

    </Global>

    <Phase number="1">
        <Node id="ltreader1" type="LOOKUP_TABLE_READER" lookupTableName="lt1" />
        <Node id="trash1" type="TRASH" debugOutput="true" />
        <Edge id="edge1" fromNode="ltreader1:0" toNode="trash1:0" metadata="meta1" />
    </Phase>

</Graph>

DATABASE_READER

DATABASE_READER считывает данные из базы данных. Поддерживает подключение к СУБД PostgreSQL, Oracle, MySQL. Подробнее про подключение к базам данных можно прочитать в разделе Соединения с базами данных.

DATABASE_READER считывает данные из базы данных

Порты DATABASE_READER:

Тип портаНомерОбязательныйОписаниеМетаданные
Output0даДля корректных записейЛюбые, но одинаковые на всех подключённых портах
1-nнет

Атрибуты DATABASE_READER:

АтрибутОбязательныйОписаниеВозможные значения
dbConnectionдаИдентификатор соединения с базой данных, которое будет использоваться для доступа к базе данных

<Connection id="conn0" dbURL="postgres://admin:admin@localhost:5432/dev"/>
sqlQueryдаSQL-запрос к базе, определенный в графе.

<attr name="sqlQuery">
<![CDATA[
    select * from table;
]]>
</attr>

Пример. Чтение записей из баз данных.

С помощью DATABASE_READER нужно прочитать данные из разных баз и записать ответы в текстовые файлы.

Решение:

  1. Для чтения данных понадобится три компонента DATABASE_READER и три компонента FLAT_FILE_WRITER - для записи данных в файлы.

  2. Создам подключения к базам postgres, sqlserver через локального клиента и к firebird через odbc. Везде буду подключаться к схеме onebridge, к таблице million_row.

  3. Для создания соединений с базами нужно на панели Outline выбрать в контекстном меню элемента Connection пункт New connection - для создания нового подключения или Link connection - для вставки ссылки на уже описанное в отдельном файле подключение. В редакторе новых соединений выбрать тип подключения и заполнить атрибут URL значениями параметров, необходимых для подключения.

Connection для postgres:

URL = "postgres://user:password@host:port/database;"

Connection для sqlserver:

URL = "sqlserver:server=sbar-dev-db02.sbar.local,port;user=username;password=password;"

Connection для firebird:

URL = "odbc:Driver={Firebird};User=username;Password=password;Database=sbar-dev-db03.sbar.local/3050:/opt/firebird/data/onebrige-dev.fdb;Charset=;Role=;ReadOnly=No;NoWait=No;"
  1. SQL-запрос для чтения данных из базы будет везде примерно одинаковый, его нужно вставить в атрибут sqlQuery внутри редактора каждого из шагов DATABASE_READER:
select BigIntColumn,
    BooleanColumn,
    CharColumn,
    DateColumn,
from onebridge.million_row
order by BigIntColumn
limit 10

Этот запрос считает значения полей BigIntColumn, BooleanColumn, CharColumn, DateColumn из таблицы million_row во внутреннюю память системы.

  1. С помощью метаданных, назначенных ребрам графа, данные будут переданы в FLAT_FILE_WRITER`ы, которые запишут их в текстовые файлы.

DATA_GENERATOR

DATA_GENERATOR генерирует данные по шаблону, вместо чтения данных из файла, базы данных или любого другого источника данных. Этот шаг может отправлять разные записи на разные выходные порты, используя возвращаемые значения функции generate.

Порты DATA_GENERATOR:

Тип портаНомерОбязательныйОписаниеМетаданные
Output0даДля сгенерированных записейЛюбые
1-nнет

Метаданные на выходных портах могут отличаться.

Атрибуты DATA_GENERATOR:

АтрибутОбязательныйОписаниеВозможные значения
generateдаОпределение способа создания записей, записанное в графе на языке преобразований
<attr name="generate">
    <![CDATA[
    let counter = 4;

    function generate() {
        counter+=1;
        $out[0].foo = counter;

        return ALL;
    }
    ]]>
</attr>
recordsNumberнетКоличество записей, которые необходимо создать. Отрицательное значение позволяет создать количество записей, ограниченное кодом в generate.recordsNumber="1"

SPREADSHEET_READER

SPREADSHEET_READER считывает данные с указанных листов файлов формата .xls или .xlsx. Позволяет указывать маппинг данных из таблицы и метаданных OneBridge. Удаленные файлы доступны для чтения через протоколы FTP и SFTP.

Должен иметь один выходной порт для успешно считанных записей.

Порты SPREADSHEET_READER:

Тип портаНомерОбязательныйОписаниеМетаданные
Output0даДля успешно считанных записейЛюбые
1неДля некорректных считанных записей

Атрибуты SPREADSHEET_READER:

АтрибутОбязательныйОписаниеВозможные значения
fileURLдаПуть к файлу проекта, из которого читать данные. Для обращения по FTP используйте шаблон ftp://username:password@hostname:port/path-to-filefileURL="testFile.txt"
sheetнетНазвание или номер листа в excel документе. Нумерация страниц начинается с 0. Можно перечислить в атрибуте sheet через запятую либо указать множество листов с помощью «*», чтобы все листы читались по порядку с использованием одного маппинга для всех.sheet="Sheet1"
mappingнетСопоставляет ячейки электронной таблицы с полями OneBridge.
<Node fileURL="ssr01_in.xlsx" id="SPREADSHEET_DATA_READER" sheet="Sheet1" type="SPREADSHEET_READER">
	<attr name="mapping">
		<![CDATA[<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
			<mapping>
                <globalAttributes>
                    <orientation>VERTICAL</orientation>
                    <step>1</step>
                    <writeHeader>false</writeHeader>
                </globalAttributes>
                <defaultSkip>1</defaultSkip>
                <headerGroups>
                    <headerGroup skip="1">
                        <autoMappingType>ORDER</autoMappingType>
                        <headerRanges>
                            <headerRange begin="A2"/>
                            <headerRange begin="B2"/>
                        </headerRanges>
                    </headerGroup>
                </headerGroups>
            </mapping>
		]]>
	</attr>
</Node>
passwordнетПароль для расшифровки файла,если он запаролен. Актально только для формата xlsx.password="faihfi4t9(&Yhflaieg)"

Пример. Сопоставление полей по порядку.

Нужно прочитать из файла таблицы с количеством проданных некой компанией товаров за первый квартал года. Таблицы имеют одинаковую структуру: название товара, январь, февраль, март. Компания международная. Каждый партнер может использовать свой язык, поэтому вы не можете сопоставить поля по имени.

лист 1:

ProductJanuaryFebruaryMarch
T1620600700
T2150150100

лист 2:

ТоварЯнварьФевральМарт
T1500400600
T2300400500

Решение:

Укажите атрибуты: fileURL, sheet, mapping.

Заполните маппинг следующим образом:

<Node fileURL="${DATAIN_DIR}/Book2.xlsx" sheet="*" type="SPREADSHEET_READER">
<attr name="mapping"><![CDATA[<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<mapping>
    <globalAttributes>
        <orientation>VERTICAL</orientation>
        <step>1</step>
        <writeHeader>true</writeHeader>
    </globalAttributes>
    <defaultSkip>1</defaultSkip>
    <headerGroups>
        <headerGroup skip="1">
            <autoMappingType>ORDER</autoMappingType>
            <headerRanges>
                <headerRange begin="A1"/>
                <headerRange begin="B1"/>
                <headerRange begin="C1"/>
                <headerRange begin="D1"/>
            </headerRanges>
        </headerGroup>
    </headerGroups>
</mapping>
]]></attr>
</Node>

Для записи данных

Шаги для записи данных могут записывать данные в локальные выходные файлы, отправлять их через подключенный дополнительный выходной порт или вставлять в таблицу базы данных.

Шаги для записи — это компоненты графа, которые выполняются последними, поэтому они не имеют выходных портов.

Каждый шаг для записи должен иметь хотя бы один входной порт, через который данные поступают в этот компонент графа.

Шаги для записи могут либо добавлять данные в существующий файл или таблицу базы данных, либо заменять существующее содержимое новым. Для этой цели шаги для записи в файлы имеют атрибут Append. По умолчанию для этого атрибута установлено значение false. Это означает, что данные необходимо заменить, а не добавить к имеющимся.

Данные можно записать в один и тот же файл или базу данных несколько раз в течение работы графа с помощью нескольих шагов для записи. Для этого разместите шаги для записи в разных фазах графа.

Общие свойства шагов для записи

Поддерживаемые форматы URL-адресов для записывающих шагов

Запись в локальные файлы

  • /path/filename.out - записывает указанный файл на диск.

Просмотр записанных данных

После создания выходного файла вы можете просмотреть данные в нём в web-приложении на странице проектов на вкладке "Содержимое файла".

Добавление или перезапись

Если целевой файл существует, есть два варианта:

  • существующий файл можно заменить;
  • записи могут быть добавлены к существующему содержимому.

Добавление или замена настраивается с помощью атрибута Append.

  • Если для параметра Append установлено значение true, записи добавляются в файл.
  • Если для параметра Append установлено значение false, файл перезаписывается. Append=false по умолчанию.

Функция Append доступна в следующих шагах для записи: FLAT_FILE_WRITER, TRASH.

FLAT_FILE_WRITER

FLAT_FILE_WRITER записывает данные в плоские файлы. Удаленные файлы доступны для записи через протоколы FTP или SFTP.

Порты FLAT_FILE_WRITER:

Тип портаНомерОбязательныйОписаниеМетаданные
Input0даДля входящего потока записейЛюбые

Атрибуты FLAT_FILE_WRITER:

АтрибутОбязательныйОписаниеВозможные значения
fileURLдаПуть к файлу, в который должен быть записан результирующий набор данных. Для обращения по FTP используйте шаблон ftp://username:password@hostname:port/path-to-file${WRITE_DIR}/out.txt
charsetнетКодировка файла, читаемого с помощью этого шага. charset="UTF-8" по умолчаниюencoding="windows-1251"
appendнетЕсли записи печатаются в существующий непустой файл, они по умолчанию заменяют более старые (при append="false"). Если установлено значение "true", новые записи добавляются в конец существующего содержимого выходного файла(ов).append="false" по умолчанию

quotedStrings

нетПри quotedStrings="true" все поля заключаются в кавычки.quotedStrings="true"

quoteChar

нетСимволы, в которые будет заключено значение поля при quotedStrings="true".quoteChar="&quot;"

fieldDelimiter

нетРазделитель полейfieldDelimiter=","

recordDelimiter

нетРазделитель записейrecordDelimiter="/n"

Пример. Запись данных в файл.

Например, нужно записать обработанные системой данные в файл, используя разделитель «|».

Данные в системе:

datelast_namefirst_name
01.02.2011ГончаровАлексей
29.12.2013НечаевИлья
25.11.2016ВаськинНиколай
23.10.2019СеровГригорий
19.09.2022ГлинкаЕвгений

Данные, записанные шагом FLAT_FILE_WRITER в файл:

01.02.2011|Горилов|Алексей
29.12.2013|Нечаев|Илья
25.11.2016|Васькин|Николай
23.10.2019|Иванов|Григорий
19.09.2022|Горбунов|Евгений

RAW_WRITER

RAW_WRITER записывает обрабатываемые данные во внутренние файлы формата OneBridgeFile.

Порты RAW_WRITER:

Тип портаНомерОбязательныйОписаниеМетаданные
Input0даДля полученных записей данныхЛюбые
Output0нетДля записи на выходной портс типом данных byte/cbyte

Атрибуты RAW_WRITER:

АтрибутОбязательныйОписаниеВозможные значения
fileURLдаАтрибут, указывающий, куда будут записаны полученные данные.fileURL="${DATATMP_DIR}/bl/${trgFilePath}/loadHub/${tableName}.sql"
appendПо умолчанию новые записи перезаписывают старые. Если установлено значение true, новые записи добавляются к старым записям, хранящимся в выходном файле(ах). append="false" по умолчанию append="true"

Пример. Запись данных во внутренний формат.

Чтобы записать данные в файл ${DATAOUT_DIR}/my-file.obf нужно заполнить атрибут fileURL.

АтрибутЗначение
fileURL${DATAOUT_DIR}/my-file.obf

RAW_WRITER запишет данные в указанный файл.

Пример. Добавление к существующему файлу.

Добавить записи каждого запуска графа в существующий файл ${DATAOUT_DIR}/my-file.obf. Для этого нужно заполнить атрибут fileURL и append.

АтрибутЗначение
fileURL${DATAOUT_DIR}/my-file.obf
appendtrue

LOOKUP_TABLE_WRITER

Шаг LOOKUP_TABLE_WRITER записывает данные в хеш-таблицу (Lookup Table).

Порты LOOKUP_TABLE_WRITER:

Тип портаНомерОбязательныйОписаниеМетаданные
Input0дадля записываемых в хеш-таблицу записей.Любые

Атрибуты LOOKUP_TABLE_WRITER:

АтрибутОбязательныйОписаниеВозможные значения
lookupTableNameдаИмя хеш-таблицы.lookupTableName="lt2"

Следующий пример графа демонстрирует генерацию данных и запись в хеш-таблиц с именем lookupTable002:


<Graph>
    <Global>
        <Metadata id="meta">
            <Record>
                <Field name="n" type="integer"/>
                <Field name="b" type="boolean"/>
            </Record>
        </Metadata>
        <LookupTable id="lookup_table1" key="n" metadata="meta" name="lt1" file="lookupTable002" />
    </Global>
    <Phase number="0">
        <Node id="datagen1" type="DATA_GENERATOR" recordsNumber="4">
            <attr name="generate">
                <![CDATA[
                let i = 0;

                function generate() {
                    $out[0].n = i;
                    $out[0].b = (i % 2 == 0) ? true : false;
                    
                    i++;

                    return ALL;
                }
                ]]>
            </attr>
        </Node>
        <Node id="ltwriter" type="LOOKUP_TABLE_WRITER" lookupTableName="lt1" />
        <Edge id="edge1" fromNode="datagen1:0" toNode="ltwriter:0" metadata="meta" />
    </Phase>
</Graph>

DATABASE_WRITER

DATABASE_WRITER предназначен для выгрузки обработанной информации в базу данных и совершения изменений в базе. Позволяет выполнять несколько SQL-запросов в рамках одной транзакции, для этого выражения в атрибуте sqlQuery разделяются точкой с запятой.

Поддерживает подключение к базам MySQL, Oracle, PostgreSQL.

Подробнее про подключение к базам данных можно прочитать в разделе Соединения с базами данных.

Порты DATABASE_WRITER:

Тип портаНомерОбязательныйОписаниеМетаданные
Input0даЗаписи для загрузки в базу данныхЛюбые
Output0нетДля отклонённых записейТакие же, как на входном порте
Output1нетДля возвращаемых значенийЛюбые

Атрибуты DATABASE_WRITER:

АтрибутОбязательныйОписаниеВозможные значения
dbConnection да Параметры соединения с базой данных. В список параметров для подключения могут входить: database, user, password, host, port. Параметры можно указать в атрибуте конкретного шага либо в глобальных параметрах графа.
dbConnection="postgres://admin:admin@localhost:5432/dev"  
sqlQuery нет

Запрос к базе. Обращение по имени поля производится с помощью специального символа $.


        insert into test_table (num,str,test_date) 
        values($num,$str,$test_date) 
        returning str;

batchMode нет Определяет режим записи в таблицу. Записывать сразу по несколько записей – true, по одной – false. Пакетный режим ускоряет загрузку данных в базу. batchMode="true"
batchSize нет Количество записей, которое можно отправить в базу данных за одно пакетное обновление (в одном sql скрипте). Актуально если batchMode="true". batchSize="5"
commit нет Определяет, после обработки скольких записей (без ошибок) выполняется коммит (фиксация записей в базе данных). Возможные значения -1,0,N:
  • commit = N - коммит делается после обработки N записей, команд при этом выполнится N*количество команд в шаге.
  • commit = 0 - коммит не делается внутри партии. если commit < batchSize, то мы считаем, что commit = batchSize, фиксируем в конце каждой партии; если commit > batchSize, но не кратен ему, то мы округляем значение вверх до первого кратного размеру batchSize. Примеры: commit = 3, batchSize = 10 => commit = 10 commit = 15, batchSize = 10 => commit = 20 commit = 20, batchSize = 10 => commit = 20 commit = 25, batchSize = 10 => commit = 30
  • commit = -1 - Если установлено такое значение, компонент никогда не выполняет фиксацию, то есть до тех пор, пока соединение не будет закрыто во время освобождения графа.коммит делается только в конце обработки всех записей
commit="10"
maxErrorCount нет Максимальное количество разрешенных ошибок. При превышении этого числа ошибок граф выходит из строя. По умолчанию ошибки не допускаются. Если установлено значение -1, все ошибки разрешены. maxErrorCount="0"
actionOnError нет Действие при превышении допустимого количества ошибок maxErrorCount. Если установлено значение ROLLBACK, фиксация текущего пакета не выполняется (актуально только для Oracle). Commit для Postgres делает тоже, что и Rollback, MsSql автоматически делает Rollback. actionOnError="commit"

Пакетный режим и размер пакета

Пакетный режим ускоряет загрузку данных в базу данных.

Оператор возврата недоступен в пакетном режиме.

Помните, что некоторые базы данных возвращают как отклоненные больше записей, чем реально отклонено. Эти базы данных возвращают даже те записи, которые были успешно загружены в базу данных, и отправляют их через выходной порт 0 (если он подключен).

  1. batchMode
  2. batchSize

Пример. Загрузка записей из OneBridge в SQLite.

Нужно загрузить данные из OneBridge в базу данных SQLite в таблицу Tracking, в поля client, items, total.

Данные в системе:

customerproductamount_of_purch
JazzveCoffeeCoffea arabica19513
Arabica Legasy LLCCoffea canephora12735
BlackBean GroupExcelsa34010

Решение:

Задайте соединение с базой:


<Connection id="CONN_A" dbURL="${CONN_TYPE}://${DB_01_USR}:${DB_01_PWD}@${DB_01_HOST}:${DB_01_PORT}/${DB_01_DATABASE}"/>

Пропишите в файл задания SQL-запрос:


<Phase ...>
    ...
    <Node id="db_writer" guiX="250" guiY="100" guiName="DatabaseWriter" dbConnection="CONN_A" type="WriterDB">
        <Attr name= “sqlQuery”><![CDATA[
            INSERT INTO public."Tracking" ("client", "items", "total")
            VALUES ($customer, $product, $amount_of_purch)
        ]]></Attr>
    </Node>
    ...
</Phase>

Чтобы вставить значения полей из системы нужно указать название полей из метаданных после знака «$».

Данные будут выгружены в базу данных, соответствующую указанному типу соединения, в таблицу Tracking.

POSTGRESQL_DATA_WRITER

POSTGRESQL_DATA_WRITER массовый загрузчик, подходящий для загрузки большого количества записей в базу данных PostgreSQL. Считывает данные через входной порт. Использует специальную утилиту Copy, которая позволяет загружать данные очень быстро. Для остальных случаев лучше использовать DATABASE_WRITER, для которого не требуется использование специальной утилиты.

Порты POSTGRESQL_DATA_WRITER:

Тип портаНомерОбязательныйОписаниеМетаданные
Input1-nдаЗаписи для загрузки в базу данныхЛюбые

Атрибуты POSTGRESQL_DATA_WRITER:

АтрибутОбязательныйОписаниеВозможные значения
dbConnection да Параметры соединения с базой данных. В список параметров для подключения могут входить: database, user, password, host, port. Параметры можно указать в атрибуте конкретного шага либо в глобальных параметрах графа.

dbConnection="postgres://admin:admin@localhost:5432/dev"

tableдаИмя таблицы, в которую производится запись

table="${tableNameTo}"

parametersнетПараметры, которые могут использоваться в качестве параметров утилитой psql или оператором \copy. Указывается последовательность ключ=значение, отделенные друг от друга точкой с запятой, двоеточием или вертикальной чертой. Если значение какого-либо параметра содержит точку с запятой, двоеточие или вертикальную черту, такое значение должно быть заключено в двойные кавычки. Сейчас доступны к указанию columns

parameters="columns=&quot;${COLUMNS}&quot;"

Пример.

Необходимо загрузить записи с метаданными «Product» (string), «Amount» (int), «date» (date) и «Price» (float) в таблицу Products в базу данных postgres с именем пользователя user001.

Укажите параметры подключения в атрибутах графа и шага POSTGRESQL_DATA_WRITER:

<Connection id="CONN" name="dev" dbURL="postgres://username:admin@localhost:5432/test"/>
<GraphParameters>
	<GraphParameter name="COLUMNS" value="my_boolean,my_integer,my_number,my_decimal,my_string" public="true" />
</GraphParameters>
...
<Node id="psql_writer" dbConnection="CONN" table="my_data_test" parameters="columns=&quot;${COLUMNS}&quot;" type="POSTGRESQL_DATA_WRITER" />

Данные будут внесены в базу:

POSTGRESQL_DATA_WRITER записывает данные в базу PostgreSQL

TRASH

TRASH используется для прерывания потока данных, когда не нужно передавать данные дальше. Шаг не имеет выходных портов.

TRASH прерывает поток данных.

TRASH прерывает поток данных

Порты TRASH:

Тип портаНомерОбязательныйОписаниеМетаданные
Input1-nнетДля входящего потока записей.Любые

Атрибуты TRASH:

АтрибутОбязательныйОписаниеВозможные значения
debugOutputнетПо умолчанию все записи удаляются. Если установлено значение true, все записи записываются в лог на вкладку «Консоль». Этот режим поддерживается при подключении любого количества входных портов.debugOutput="true"

Для преобразования данных

Преобразователи — это промежуточные шаги графа. Преобразователи получают данные через подключенные входные порты, обрабатывают их указанным пользователем способом и отправляют через подключенные выходные порты в следующие шаги.

Список шагов-преобразователей данных:

EXT_SORT

EXT_SORT сортирует полученные записи в соответствии с указанным ключом сортировки и копирует каждую из них на все подключенные выходные порты. Позволяет использовать несколько параллельных потоков для сортировки больших данных.

Порты EXT_SORT:

Тип портаНомерОбязательныйОписаниеМетаданные
Input0даДля входящего потока записейОдинаковые метаданные на входных и выходных портах
Output0даДля отсортированных записей
1-nнетДля отсортированных записей

Атрибуты EXT_SORT:

АтрибутОбязательныйОписаниеВозможные значения
sortKeyдаСписок полей метаданных, по которым производится сортировка и в скобках - порядок сортировки. Наивысший приоритет сортировки имеет первое поле в последовательности. Порядок сортировки выражается отдельно для каждого ключевого поля. По возрастанию - `a` (от англ. ascending - восходящий) или по убыванию - `d` (от англ. descending - нисходящий). Порядок сортировки по умолчанию — `a` — по возрастанию.

sortKey="x_coord(a); y_coord(d)"

sortInMemoryнет

При sortInMemory="true" выполняется внутренняя сортировка. По умолчанию false.

sortInMemory="true"
runSizeнет

Количество записей, сортируемых одновременно в памяти; размер одного буфера чтения. По умолчанию 8192.

runSize="15456"

Пример. Сортировка данных.

Входные записи содержат имена файлов и их размер. Нужно отсортировать файлы по размеру, начиная с самого большого (descending – по убыванию). Метаданные содержат поля «FileName», «FileSize».

Входящие записи:

FileNameFileSize
file.txt2048
file.docx1048576
file.xml65536

Решение:

Ключ сортировки: sortKey="FileSize(d)"

Исходящие записи:

FileNameFileSize
file.docx1048576
file.xml65536
file.txt2048

EXT_FILTER

EXT_FILTER фильтрует входные данные в соответствии с логическим выражением. Отправляет все записи, соответствующие выражению фильтра, в первый выходной порт и все отклоненные записи во второй выходной порт.

Порты EXT_FILTER:

Тип портаНомерОбязательныйОписаниеМетаданные
Input0даДля входящего потока записейОдинаковые метаданные на входных и выходных портах
Output0даДля отфильтрованных записей
1нетДля отклонённых записей

Атрибуты EXT_FILTER:

АтрибутОбязательныйОписаниеВозможные значения
filterExpressionдаВыражение, по которому фильтруются записи.

($in[0].count != 177) && ($in[0].product == "карандаш") 
 

Пример. Фильтрация данных.

Входные данные содержат данные о продуктах, проданных в прошлом году. Нужно узнать данные только по карандашам. Метаданные содержат поля Product, Count и Location.

Входящие записи:

ProductCountLocation
карандаш1553екатеринбург
бумага6475новгород
ручка598владикавказ
карандаш177омск
карандаш239волгоград
бумага19казань
ластик53ростов

Решение:

Выражение для фильтрации: $in[0].product == "карандаш"

Исходящие записи:

ProductCountLocation
карандаш1553екатеринбург
карандаш177омск
карандаш239волгоград

GATHER

GATHER собирает записи со всех входящих портов и отправляет в порядке получения на все выходные порты. Порядок получения записей не зависит от порядка входных портов. Этот шаг соблюдает порядок записей в потоках, но не соблюдает порядок потоков. На выходе получается список записей в непредсказуемом порядке. Порядок записей на разных выходах будет одинаков. Шаг не имеет атрибутов.

Порты GATHER:

Тип портаНомерОбязательныйОписаниеМетаданные
Input0даДля входящего потока записейОдинаковые метаданные на входных и выходных портах
1-nнетДля входящего потока записей
Output0даДля отфильтрованных записей
1-nнетДля отклонённых записей

Пример. Сбор записей с нескольких входных портов.

Нужно собрать записи с нескольких потоков. Потоки содержат одно поле - "id".

Входящие записи:

GATHER input

Решение:

  1. Создать метаданные: имя="id", тип="integer"

  2. Поместить компоненты, передающие данные и GATHER на рабочую область.

  3. Соединить шаги ребрами и назначить рёбрам метаданные.

  4. После запуска графа записи со всех портов будут объединены:

GATHER output

SIMPLE_COPY

SIMPLE_COPY получает записи через один входной порт и копирует каждую из них на все подключенные выходные порты. Шаг не имеет атрибутов.

Порты SIMPLE_COPY:

Тип портаНомерОбязательныйОписаниеМетаданные
Input0даДля входящего потока записейЛюбые
Output0даДля скопированных записейКак у Input 0
1-nнетКак у Output 0

Пример. Копирование данных.

Нужно скопировать записи с метаданными «carID» и «mark» в три потока.

Входящие записи:

порт 0:

carIDmark
145mercedes
856toyota
245chevrolet

Решение:

Для копирования в несколько потоков нужно подключить SIMPLE_COPY несколько выходных портов. Записи на всех выходных портах будут идти в одинаковом порядке.

Исходящие записи:

порт 0:

carIDmark
145mercedes
856toyota
245chevrolet

порт 1:

carIDmark
145mercedes
856toyota
245chevrolet

порт 2:

carIDmark
145mercedes
856toyota
245chevrolet

MAP

MAP позволяет написать пользовательский алгоритм обработки данных, используя внутренний язык системы. Можно по своему усмотрению трансформировать данные между входным и выходными портами, если предложенных шагов не хватает для выполнения необходимых преобразований данных.

Имеет единственный входной порт и как минимум один выходной. Может отправлять разные записи в разные выходные порты или даже отправлять одну и ту же запись на несколько выходных портов. Работает только с одним элементом, сохраняет порядок записей.

С помощью MAP можно:

  • удалить ненужные значения полей
  • проверить записи с помощью функций или регулярных выражений
  • создать новые или изменить существующие поля
  • преобразовать типы данных

Порты MAP:

Тип портаНомерОбязательныйОписаниеМетаданные
Input0даДля входящего потока записейЛюбые
Output0даДля преобразованных записей
1-nнет

Атрибуты MAP:

АтрибутОбязательныйОписаниеВозможные значения
transformдаАлгоритм преобразования данных

<attr name="transform">
    <![CDATA[
        function transform() {
            $out[0].person = $in[0].name.toString() + "_" + $in[0].surname.toString();
            $out[1].person = $in[0].name.toString().toUpperCase() + " " + $in[0].surname.toString().toUpperCase();
            return ALL;
        }
    ]]>
</attr>

Пример. Обработка данных с помощью MAP.

Нужно получить произведение и сумму полученных на вход данных и отправить результаты на разные выходные порты. Входные метаданные содержат поля a, b. Нужно отправить результат перемножения a*b на первый порт, а результат сложения a+b на второй порт.

Входящие записи:

ab
56
24
12

Решение:

Преобразование:


<Attr name="transform"><![CDATA[
    function transform() {
    //transform code
        var res_mul = $in[0].a * $in[0].b;
        var res_add = $in[0].a + $in[0].b;

        $out[0].res_mul = res_mul;
        $out[1].res_add = res_add;

        return ALL;
    }
    ]]>
</Attr>

Исходящие записи:

порт 0:

multiplied
30
6
2

порт 1:

added
11
5
3

ROLLUP

ROLLUP создает одну или несколько выходных записей из одной или нескольких входных записей. Может отправлять разные записи на разные выходные порты, указанные пользователем. Записи должны быть отсортированы перед подачей в этот шаг.

Метаданные на разных выходных портах могут различаться.

Порты ROLLUP:

Тип портаНомерОбязательныйОписаниеМетаданные
Input0даДля входных записейлюбые
Output0даДля выходных записей
1-Nнет

Атрибуты ROLLUP:

АтрибутОбязательныйОписаниеВозможные значения
groupKeyFieldsдаКлюч, по которому записи считаются включенными в одну группу. Выражается в виде последовательности имен отдельных входных полей, разделенных друг от друга символом «#».name; salary
groupAccumulatorMetadataIdдaИдентификатор метаданных, которые служат для создания групповых аккумуляторов.metadataName
transformдаАлгоритм обработки данных. Функции для преобразования на шаге ROLLUP описаны в таблице ниже.
function initGroup(groupAccumulator) {
    groupAccumulator.metaFieldName = 0;
}

function updateGroup(groupAccumulator) {
    groupAccumulator.metaFieldName = groupAccumulator.metaFieldName + $in[0].metaFieldName;
    return false;
}

function finishGroup(groupAccumulator) {
    return true;
}

function updateTransform(counter, groupAccumulator) {
    return SKIP;
}

function transform(counter, groupAccumulator) {
    if(counter > 0) return SKIP;
    $out[0] = $in[0];
    $out[0].metaFieldName = groupAccumulator.metaFieldName;
    return ALL;
}

Схема работы шага ROLLUP

Схема работы шага ROLLUP

Функции шага ROLLUP

Когда приходит первая запись, срабатывает initGroup(groupAccumulatorMetadataId). Он инициализирует группу записей, объединенных групповым акумулятором groupAccumulatorMetadataId.

ПараметрЗначение
ОбязательныйДа
Входные параметры

groupAccumulatorMetadataId - имя метаданных, указываемое пользователем. Если groupAccumulatorMetadataId не определён, выполнение графа завершится с ошибкой.

Возвращаетvoid
ВызовВызывается по одному разу для первой входной записи каждой группы. Вызывается перед updateGroup(groupAccumulatorMetadataId).
ОписаниеОбновляет информацию для конкретной группы.
Пример

groupAccumulatorMetadataId = out_rlp

function initGroup(out_rlp) {
  group = $in[0].field;
  num = 0;
}

Далее для каждой записи, которая соответствует этой группе, вызывается updateGroup(groupAccumulatorMetadataId).

ПараметрЗначение
ОбязательныйДа
Входные параметры

groupAccumulatorMetadataId - имя метаданных, указываемое пользователем. Если groupAccumulatorMetadataId не определён, выполнение графа завершится с ошибкой.

Возвращает

если true, то вызывается updateTransform(counter, groupAccumulatorMetadataId)

если false, то граф завершится с ошибкой.

Вызов

Вызывается многократно (по одному разу для каждой входной записи группы, включая первую и последнюю запись). Вызывается после того, как функция initGroup(groupAccumulatorMetadataId) уже была вызвана для всей группы.

ОписаниеИнициализирует информацию для конкретной группы.
Пример
function updateGroup(out_rlp) {
  num = $in[0].num + num;

  return true;
}

Если updateGroup вернул true, то для каждой записи еще вызывается updateTransform(counter, groupAccumulatorMetadataId) столько раз сколько указан counter внутри, пока не вернётся SKIP.

ПараметрЗначение
ОбязательныйДа
Входные параметры

Целочисленный счетчик (начинается с 0, указывает количество созданных записей. Должен быть завершен, как показано в примере ниже. Вызовы функций заканчиваются, когда возвращается SKIP.)

<metadata name> groupAccumulatorMetadataId (метаданные, указанные пользователем).

Если groupAccumulatorMetadataId не определен, выполнение графа завершится с ошибкой.

Возвращаетцелочисленные значения
Вызов

Вызывается неоднократно, как указано пользователем. Вызывается после того, как updateGroup(groupAccumulatorMetadataId) возвращает значение true. Функция вызывается до тех пор, пока не будет возвращен SKIP.

Описание

Создает выходные записи на основе информации об отдельных записях. Если updateTransform() завершится ошибкой, весь граф завершится ошибкой.

Пример
function updateTransform(counter,out_rlp) {
  if(counter > 0) return SKIP;

  $out[0].field = $in[0].field;
  $out[0].num = $in[0].num;

  return ALL;
}

Когда группа закончилась, отрабатывает finishGroup(groupAccumulatorMetadataId).

ПараметрЗначение
ОбязательныйДа
Входные параметры
<metadata name> groupAccumulatorMetadataId

Метаданные, указанные пользователем. Если groupAccumulatorMetadataId не определен, выполнение графа завершится с ошибкой.

Возвращает

если true, то вызывается transform(counter, groupAccumulatorMetadataId)

если false, то граф завершится с ошибкой.

Вызов

Вызывается повторно, один раз для последней входной записи каждой группы. Вызывается после того, как updateGroup(groupAccumulatorMetadataId) уже был вызван для всех входных записей группы.

Описание

Если finishGroup() завершается с ошибкой, то весь граф завершится ошибкой.

Пример
function finishGroup(out_rlp) {
    return true;
}

Затем выполняется transform(counter, groupAccumulatorMetadataId).

ПараметрЗначение
ОбязательныйДа
Входные параметры

целочисленный счетчик (начинается с 0, указывает количество созданных записей. должен быть завершен, как показано в примере ниже. Вызовы функций заканчиваются, когда возвращается SKIP.)

<metadata name> groupAccumulatorMetadataId (метаданные, указанные пользователем).

Если groupAccumulatorMetadataId не определен, выполнение графа завершится с ошибкой.

Возвращаетцелочисленные значения
Вызов

Вызывается неоднократно, как указано пользователем. Вызывается после того, как updateGroup(groupAccumulatorMetadataId) возвращает значение true. Функция вызывается до тех пор, пока не будет возвращен SKIP.

Описание

Создает выходные записи на основе всех записей всей группы. Если функция transform() завершается ошибкой, то весь граф завершится с ошибкой.

Пример
function transform(counter,out_rlp) {
  if(counter > 0) return SKIP;

Входные записи или поля

Входные записи или поля доступны в функциях initGroup(), updateGroup(), finishGroup(), updateTransform(), transform().

Выходные записи или поля

Выходные записи или поля доступны в функциях updateTransform(), transform().

Групповой аккумулятор

Групповой аккумулятор доступен в функциях initGroup(), updateGroup(), finishGroup(), updateTransform(), transform().

Пример. Сгруппировать записи.

На вход в ROLLUP подаются записи, некоторые из которых имеют одинаковое значение поля "num". Нужно соединить значения всех полей, у которых одинаковое значение num и подать на выходной порт.

  1. Создать метаданные.

rollin:

  • stra (string),
  • num (integer),
  • stro (string),
  1. Поместить компоненты на рабочую область.
  2. Соединить шаги ребрами и назначить им метаданные.
  3. Задать значения атрибутов шагу ROLLUP.

groupKeyFields = "num",
groupAccumulatorMetadataId = "rollin",
transform =

function initGroup(groupAccumulator) {
	groupAccumulator.s = null;
	groupAccumulator.t = 0;
	groupAccumulator.r = null;
}

function updateGroup(groupAccumulator) {
	groupAccumulator.s = groupAccumulator.s + $in[0].stra;
	groupAccumulator.t = groupAccumulator.t + $in[0].num;
	groupAccumulator.r = groupAccumulator.r + $in[0].stro;
	return true;
}

function finishGroup(groupAccumulator) {
	return true;
}

function updateTransform(counter, groupAccumulator) {
	return SKIP;
}

function transform(counter, groupAccumulator) {
	if(counter > 0) return SKIP;
	$out[0].s = groupAccumulator.s;
	$out[0].t = groupAccumulator.t;
	$out[0].r = groupAccumulator.r;
	return ALL;
}
  1. Результатом выполнения графа будут строки из входных записей, значения полей которых соединенны при условии наличия одинакового значения поля "num".

DATA_INTERSECTION

DATA_INTERSECTION получает отсортированные данные с двух портов, сравнивает их значения по ключу и обрабатывает записи следующим образом:

  • Входные записи с обоих входных портов, совпавшие по ключу, обрабатываются в соответствии с определённым в атрибуте transform преобразованием, и результат отправляется на выходной порт 1.

  • Не подошедшие по ключу записи со входного порта 0, отправляются без изменений на выходной порт 0.

  • Не подошедшие по ключу записи из порта 1 - на выходной порт 2.

Записи считаются находящимися на обоих портах, если значения всех полей ключа соединения в них совпадают.

Преобразование должно быть определено, если подключён выходной порт 1.

Перед попаданием в данный шаг данные должны быть отсортированы.

Порты DATA_INTERSECTION:

Тип портаНомерОбязательныйОписаниеМетаданные
Input0даДля входных записей (поток данных A).

Любые1

1даДля входных записей (поток данных Б).

Любые1

Output2

0нетДля неизмененных выходных записей (содержащихся только в потоке A).Как на Input 0
1нетДля измененных выходных записей (содержащихся в обоих входных потоках).Любые
2нетДля неизмененных выходных записей (содержащихся только в потоке Б).Как на Input 1
1

Часть полей метаданных должна совпадать с полями ключа соединения.

2

Хотя бы один выходной порт из трех должен быть подключён.

Атрибуты DATA_INTERSECTION:

АтрибутОбязательныйОписаниеВозможные значения
joinKeyдаКлюч, для сравнения записей из входных портов.

joinKey="$field1=$field1"

transform

обязательно, если порт Output[1] подключён

Определение способа пересечения записей со входных портов.

function integer transform() {
    $out[0] = $in[0];
    $out[1] = $in[0] + $in[1];
    $out[2] = $in[1];
return ALL;
}
equalNullнет

По умолчанию записи с нулевыми значениями ключевых полей считаются равными. Если установлено значение false, они считаются отличными друг от друга.

equalNull="true" по умолчанию

keyDuplicatesнет

Разрешает дублирование ключа. По умолчанию установлено значение true, записи с повторяющимися значениями ключей допускаются. В противном случае, для объединения используется только первая запись.

keyDuplicates="true" по умолчанию

Ключ соединения

Выражается как последовательность отдельных подвыражений, отделенных друг от друга точкой с запятой. Каждое подвыражение представляет собой присвоение имени поля из первого входного порта (с префиксом в виде знака доллара $) слева и имени поля из второго входного порта (с префиксом $) с правой стороны.

Дублирование данных

Компонент DATA_INTERSECTION может возвращать количество записей, отличное от исходного количества входных записей.

Если для параметра keyDuplicates установлено значение false, количество выходных записей может быть меньше количества входных записей, поскольку используется только первая из записей с дубликатом ключа.

Если для параметра keyDuplicates установлено значение true, количество выходных записей может быть больше, чем количество входных записей. На выходе создается декартово произведение записей, имеющих одинаковый ключ.

CONCATENATE

CONCATENATE получает записи, поступившие из первого входного порта, отправляет их на общий выходной порт и добавляет к ним записи, из остальных входных портов. Если шаг имеет более двух входных портов, записи принимаются и отправляются на выход в соответствии с порядком входных портов. Если некоторые входные порты не содержат записей, такие порты пропускаются. Шаг не имеет атрибутов.

Порты CONCATENATE:

Тип портаНомерОбязательныйОписаниеМетаданные
Input0даДля входящего потока записейЛюбые
1-nнетКак у Input 0
Output0даДля объединенных записей

Пример. Объединение записей.

Нужно объединить записи. Поданные на вход метаданные имеют поля «flower», «color».

Входящие записи:

порт 0:

flowercolor
маккрасный
ромашкабелый
василекголубой

порт 1:

flowercolor
розасиреневый
лилиярозовый

порт 2:

flowercolor
подсолнухжелтый
анемонвишневый
гипсофилазеленый

Решение:

После конкатенации будут получены следующие записи.

Исходящие записи:

порт 0:

flowercolor
маккрасный
ромашкабелый
василекголубой
розасиреневый
лилиярозовый
подсолнухжелтый
анемонвишневый
гипсофилазеленый

NORMALIZER

NORMALIZER создает одну или несколько выходных записей из каждой отдельной входной записи. Входные записи не обязательно сортировать.

Порты NORMALIZER:

Тип портаНомерОбязательныйОписаниеМетаданные
Input0даДля входных записейЛюбые
Output0даДля нормализованных записейЛюбые

Атрибуты NORMALIZER:

АтрибутОбязательныйОписаниеВозможные значения
normalizeдаОпределение способа нормализации записей
<attr name="normalize"><![CDATA[
	function count() {
	    if ($in[0].foo >= 50) {	return 1 } 
        else { return 0 }
			
	function transform() {
		$out[0].num = $in[0].foo;
		$out[0].str = "asd"+$in[0].foo/3.14;
		return ALL;
	}
]]></attr>

Для NORMALIZER нужно определить функцию преобразования. Преобразование должно быть определено в файле задания в артибуте normalize. Эта функция будет вызываться заданное количество раз для каждой записи, поданной на вход этому шагу.

Функции шага NORMALIZER:

integer count()

ПараметрЗначение
ОбязательныйДа
Входные параметрынет
ВозвращаетЧисло, которое определяет количество вызовов функции Transform() для каждой записи. Если функция count() возвращает 0, то последующий вызов Transform() не производится.
ВызовВызывается по одному разу для каждой входной записи.
ОписаниеОписывает количество повторений вызова функции transform()
Пример
function count() {
   customers = split($in[0].customers,";");
   return length(customers);
}

integer transform()

ПараметрЗначение
ОбязательныйДа
Входные параметрынет
ВозвращаетЦелое число. Число соответствует возвращаемому значению преобразования.
ВызовВызывается один раз для каждой выходной записи. Количество вызовов определяется возвращаемым значением функции count().
ОписаниеСоздает выходные записи.
Пример
function transform(idx) {
   myString = customers[idx];
   $out[0].OneCustomer = str2integer(myString);
   $out[0].RecordNo = $in[0].recordNo;
   $out[0].OrderWithinRecord = idx;

   return ALL;
}

Пример. Преобразование записи с многозначными полями в несколько записей.

Входные записи содержат название должности и список имён сотрудников. Нужно преобразовать записи в кортежи, содержащие название должности и одно имя сотрудника.

менеджер | [Егор, Алина]
разработчик | [Артём, Никита, Данил]

Решение

Определим преобразование, используя атрибут normalize:

function count() {
    return length($in[0].users);
}

function transform() {
    $out[0].group = $in[0].group;
    $out[0].user = $in[0].users;
    return ALL;
}

NORMALIZER вернёт следующие записи:

менеджер |Егор
менеджер |Алина
разработчик|Артём
разработчик|Никита
разработчик|Данил

AGGREGATE

Получает записи через один входной порт, вычисляет статистическую информацию о записях входных данных и отправляет их на все выходные порты. Требует сортировки входных записей.

Порты AGGREGATE:

Тип портаНомерОбязательныйОписаниеМетаданные
Input0даДля входных записейЛюбые
Output0-nдаДля результатов подсчетовЛюбые

Атрибуты AGGREGATE:

АтрибутОбязательныйОписаниеВозможные значения
aggregateKeyнетКлюч, по которому группируются записиkey1;key2
mappingдаОпределяет способ присвоениея входных данных к полям выходных метаданных. Выражения внутри маппинга разделяются точкой с запятой (;), перед именем поля метадаты нужно ставить доллар ($), для присвоения использовать двоеточие и равно (:=).$field1:=$field1;$res:=count(field2);$srznach:=avg($field3)
zeroCountнетОпределяет обработку отсутствия данных для определенного в артибуте aggregateKey ключа. При zeroCount=true, в случае отсутствия записей на входе в ноду, генерируется 1 запись на выход. Если установлено значение false, ни одна запись не создается.false (по умолчанию)/true

Функции AGGREGATE:

ФункцияОписаниеТип входных данныхТип выходных данных
avgВозвращает среднее арифметическое.любой числовой типnumber
countПодсчитывает количество строк, учитывает null.любойnumber
countnotnullПодсчитывает записи, если поле содержит null, оно не учитывается.любойnumber
countuniqueПодсчитывает уникальные значения. Считает null уникальным значением. любойnumber
firstВозвращает первое значение группы. любойлюбой
firstnotnullВозвращает первое значение, отличное от null. любойлюбой
lastВозвращает последнее значение группы. любойлюбой
lastnotnullВозвращает последнее значение, отличное от null. любойлюбой
maxВозвращает максимальное значение. любой числовой типлюбой числовой тип
md5любойstring
medianВозвращает медианное значение. null значения не учитываются. любой числовой типnumber
minВозвращает минимальное значение. любой числовой типлюбой числовой тип, соответствующий входному
modusВозвращает наиболее часто используемое значение (null-значения не учитываются). Если кандидатов больше, возвращается первый. типтип
sumВозвращает сумму входных значений. любой числовой типnumber
constлюбойstring

Пример. Вызов функций avg, count, max, last и sum через шаг AGGREGATE


<Graph>
  <Global>
    <Metadata id="meta0">
      <Record name="inMeta" type="delimited" recordDelimiter="\n" fieldDelimiter=",">
        <Field name="key1" type="integer"/>
        <Field name="key2" type="integer"/>
        <Field name="field1" type="number"/>
        <Field name="field2" type="number"/>
        <Field name="field3" type="number"/>
      </Record>
    </Metadata>
    <Metadata id="meta1">
      <Record name="outMeta" type="delimited" recordDelimiter="\n" fieldDelimiter=",">
        <Field name="avg" type="number"/>
        <Field name="count" type="number"/>
        <Field name="countnotnull" type="number"/>
        <Field name="countunique" type="number"/>
        <Field name="first" type="integer"/>
        <Field name="firstnotnull" type="number"/>
        <Field name="last" type="number"/>
        <Field name="lastnotnull" type="number"/>
        <Field name="max" type="number"/>
        <Field name="md5" type="string"/>
        <Field name="median" type="number"/>
        <Field name="min" type="number"/>
        <Field name="modus" type="number"/>
        <Field name="sum" type="number"/>
        <Field name="const" type="string"/>
      </Record>
    </Metadata>
  </Global>
  <Phase number="0">
    <Node id="DataGenerator0" guiX="100" guiY="50" guiName="DataGenerator" type="DATA_GENERATOR" recordsNumber="20">
      <attr name="generate"><![CDATA[// Generates output record.

function generate() {
    $out[0].key1 = Math.floor(Math.random() * 10);
    $out[0].key2 = Math.floor(Math.random() * 10);
    $out[0].field1 = Math.floor(Math.random() * 1000);
    $out[0].field2 = Math.floor(Math.random() * 1000);
    $out[0].field3 = Math.floor(Math.random() * 1000);
    return ALL;
}]]></attr>
    </Node>

    <Node id="Sort0" guiX="300" guiY="50" guiName="Sort" type="EXT_SORT" sortKey="key1;key2">
    </Node>    
    <Node id="FlatFileWriter0" guiX="700" guiY="50" guiName="FlatFileWriter0" type="FLAT_FILE_WRITER" fileURL="aggregate.csv" />

    <Edge id="Edge0" fromNode="DataGenerator0:0" toNode="Sort0:0" metadata="meta0"/>
    <Edge id="Edge2" fromNode="Sort0:0" toNode="FlatFileWriter0:0" metadata="meta0"/>
    <Edge id="Edge1" fromNode="Sort0:1" toNode="Aggregate0:0" metadata="meta0"/>
  </Phase>

  <Phase number="1">
    <Node id="Aggregate0" guiX="500" guiY="150" guiName="Aggregate" aggregateKey="city" zeroCount="true" mapping="$avg:=avg($key1);$count:=count($key1);$countnotnull:=countnotnull($key2);$countunique:=countunique($key2);$first:=first($key1);$firstnotnull:=firstnotnull($field2);$last:=last($field2);$lastnotnull:=lastnotnull($field2)" type="AGGREGATE">
    </Node>
    <Edge id="Edge3" fromNode="Aggregate0:0" toNode="FlatFileWriter1:0" metadata="meta1"/>

    <Node id="FlatFileWriter1" guiX="700" guiY="150"  guiName="FlatFileWriter0" type="FLAT_FILE_WRITER" fileURL="agg.csv" />
  </Phase>
</Graph>

DEDUP

DEDUP удаляет повторяющиеся записи по ключу. Требует сортировки входных записей.

Порты DEDUP:

Тип портаНомерОбязательныйОписаниеМетаданные
Input0даДля входных записейЛюбые
Output0даДля дедуплицированных записей.Как у Input 0
Output1нетДля дубликатов записей.Как у Input 0

Атрибуты DEDUP:

АтрибутОбязательныйОписаниеВозможные значения
dedupKeyнетКлюч, по которому производится дедупликация (удаление дубликатов) записей. Если ключ не установлен, весь входной поток рассматривается как одна группа и удаляются только полные дубликаты (по всем полям записи).dedupKey="x_coord"
keepнетОпределяет, какие записи будут сохранены. В случае значения Unique все записи из входного потока, где по ключу находится больше 1 записи, отбрасываются на порт output[1]. В случае значения First и Last туда идут только те записи, которые не прошли дедупликацию.

"first" (деф.) - Сохраняются записи из начала потока.
"last" - Сохраняются записи из конца потока.
"unique" - Выбираются только записи без дубликатов, в этом случае numberOfDuplicates игнорируется.

keep="unique"
numberOfDuplicatesнетМаксимальное количество повторяющихся записей, которые необходимо выбрать из каждой группы записей с одинаковым значением ключа или, если ключ не задан, максимальное количество записей с начала или конца всех записей. Игнорируется, если установлен keep="Unique".numberOfDuplicates="2"

Пример. Дедупликация несортированных записей.

Записи содержат время входов на некоторый ресурс с различных ip адресов. Нужно найти время первого входа для каждого ip адреса. Метаданные содержат поля «ip» и «time».

Входящие записи:

iptime
67.249.105.11811:46:12
208.25.71.8805:14:15
161.100.209.23523:12:32
161.100.209.23523:19:34
67.249.105.11815:34:09
223.78.208.18415:35:43
52.151.181.421:51:17
223.78.208.18415:38:49
161.100.209.23523:28:16

Решение:

Перед передачей в DEDUP данные надо прочитать и отсортировать. Для сортировки укажем ключ sortKey="ip(a);time(a)". При дедупликации укажем ключ: dedupKey = «ip». Текст графа будет выглядеть следующим образом:


<Graph>
  <Global>
    <Metadata id="meta0">
      <Record name="meta" type="delimited" recordDelimiter="\n" fieldDelimiter="|">
        <Field name="ip" type="string"/>
        <Field name="time" type="string"/>
      </Record>
    </Metadata>
  </Global>
  <Phase number="0">
    <Node id="FlatFileReader0" guiX="100" guiY="83" guiName="FlatFileReader" type="FLAT_FILE_READER" fileURL="dedup_in.txt">
    </Node>
    <Node id="Sort0" guiX="300" guiY="83" guiName="Sort" type="EXT_SORT" sortKey="ip(a);time(a)" sortInMemory="false">
    </Node>
    <Node id="Trash0" guiX="633" guiY="83" guiName="Trash" type="TRASH" debugOutput="true">
    </Node>
    <Node id="Dedup0" guiX="467" guiY="83" guiName="Dedup" type="DEDUP" dedupKey="ip" keep="first" numberOfDuplicates="1">
    </Node>
    <Edge id="Edge0" fromNode="FlatFileReader0:0" toNode="Sort0:0" metadata="meta0"/>
    <Edge id="Edge1" fromNode="Sort0:0" toNode="Dedup0:0" metadata="meta0"/>
    <Edge id="Edge2" fromNode="Dedup0:0" toNode="Trash0:0" metadata="meta0"/>
  </Phase>
</Graph>

Исходящие записи:

iptime
67.249.105.11811:46:12
208.25.71.8805:14:15
161.100.209.23523:12:32
223.78.208.18415:35:43
52.151.181.421:51:17

Для объединения данных

Шаги этой группы называются "Соединители". Они служат для объединения записей из потоков с потенциально разными метаданными в соответствии с заданным ключом соединения и способом преобразования.

Соединители имеют как входные, так и выходные порты. Первый входной порт шага-соединителя называется "главным" или "мастером" и обозначается номером «0», остальные входные порты — "подчинённые".

Соединители всегда объединяют только записи из главного порта с записями из подчинённых портов. И не объединяют записи из ведомых портов между собой.

HASH_JOIN

HASH_JOIN объединяет потоки данных по ключу.

Этот шаг получает данные через два или более входных порта, каждый из которых может иметь различную структуру метаданных. Записи не обязательно сортировать перед передачей в этот шаг.

Сначала HASH_JOIN считывает записи из всех подчинённых портов и сохраняет их в хэш-таблицы.

Для каждого подчинённого порта создается отдельная хэш-таблица. Размер всех созданных хэш-таблиц не должен превышать размер оперативной памяти сервера, так как хэш-таблицы хранятся в оперативной памяти и ее переполнение приведет к завершению задания с ошибкой. Поэтому имеет смысл в главный входной поток подавать большое количество записей, а в подчинённые потоки – небольшие группы записей.

Затем для каждой записи из мастера производится поиск совпадения с записями из каждой хэш-таблицы по заданному ключу соединения.

Если совпадение найдено, кортеж из записи главного порта и хэш-таблицы подчинённого порта трансформируется заданным образом. Полученная после преобразования запись подаётся на первый выходной порт. Метод преобразования вызывается для каждого кортежа главной и соответствующих подчинённых записей. Записи из главного порта, которые не были объединены подаются на второй выходной порт.

Порты HASH_JOIN:

Тип портаНомерОбязательныйОписаниеМетаданные
Input0даГлавный входной портЛюбые
1даДополнительный входной порт
2-nнетОпциональные дополнительные входные порты
Output0даИсходящий порт
1нетПорт для записей, которые не подошли по ключу соединенияКак у Input 0

Атрибуты HASH_JOIN:

АтрибутОбязательныйОписаниеВозможные значения
joinKeyдаКлюч, по которому объединяются входящие потоки данных. Порты отделяются друг от друга хешем #. Сопоставление полей одного порта отделяются друг от друга точкой с запятой ';'. Перед именем каждого поля нужен знак '$'.

joinKey="$obj_type=$type#$level=$importance;$name=$user"

joinTypeнетТип объединения. Бывает "inner"(по умолчанию) и "leftOuter"joinType="leftOuter"
transformда

Преобразование, определенное в файле задания на внутреннем языке системы

    function transform() {
    $out[0].user_code = $in[0].user_id;
    $out[0].bind_code = $in[1].bind_code;
    $out[0].bind_datetime = $in[1].bind_datetime;
            
    return ALL;
slaveDuplicatesнетЕсли установлено значение true, разрешены записи с повторяющимися значениями ключей. Если false, для объединения используется только последняя запись. По умолчанию true.slaveDuplicates="false"

Пример.

Даны два потока записей. В одном потоке содержится информация о названии продукта в поле «Product» и его цвете на русском языке «rus_color», во втором потоке – названию цвета на русском языке соответствует название на английском «eng_color». Задача сопоставить продукт и его цвет на английском языке.

порт0:

productrus_color
шарфкрасный
носокбелый
свитерзеленый

порт1:

rus_coloreng_color
синийblue
желтыйyellow
красныйred

Ключ соединения: joinKey="$rus_color"

Формула для объединения:


<Attr name="transform">
<![CDATA[
    function transform() {
    //transform code
        $out[0].product = $in[0].product;
        $out[0].eng_color = $in[1].eng_color;
    return ALL;
    }
]]></Attr>

Исходящие записи:

порт0:

producteng_color
шарфred

порт1:

productrus_color
носокбелый
свитерзеленый

MERGE_JOIN

Объединяет данные из двух или более источников данных по общему ключу. Данные должны быть отсортированы перед подачей в этот шаг.

MERGE_JOIN получает данные через два или более входных порта, каждый из которых может иметь различную структуру метаданных. Затем объединенные данные отправляются на первый выходной порт. Необъединенные данные можно вывести на второй выходной порт.

Порты MERGE_JOIN:

Тип портаНомерОбязательныйОписаниеМетаданные
Input0даГлавный входной портлюбые
1даВедомый входной порт
2-nнетДополнительные ведомые входные порты
Output0даВыходной порт для объединенных данных
1нетВыходной порт для необъединённых данныхкак на Input 0

Типы полей метаданных на первом входном и втором выходном портах должны быть одинаковыми, имена полей при этом могут отличаться.

Атрибуты MERGE_JOIN:

АтрибутОбязательныйОписаниеВозможные значения
joinKeyдаКлюч, который используется для объединения входящих потоков данных. Части ключа, соответствующие определенным входным портам, отделяются друг от друга хэшем '#'. Порядок полей в ключе должен соответствовать порядку входных портов. Поля тз одного порта внутри joinKey отделяются друг от друга точкой с запятой. Каждому имени поля должен предшествовать знак доллара '$'. В скобках после полей, по которым производилась сортировка, нужно указать её направление.joinKey="$name(a);$color(d)#$product;$tint;#$name;$tone"
joinTypeнетТип объединения.inner (по умолчанию) | leftOuter
transformдаПреобразование, определенное в файле задания на внутреннем языке системы.
<attr name="transform"><![CDATA[
    function transform() {
        $out[0].id = $in[0].id;
        $out[0].name = $in[0].name;

        return ALL;
    }
    ]]>
</attr>
slaveDuplicatesнетЕсли установлено значение true, разрешены записи с повторяющимися значениями ключей. Если false, для объединения используется только последняя запись. По умолчанию true.slaveDuplicates="false"

Пример. Объединить записи из двух потоков по ключу.

  1. Описать метаданные
  2. Переместить шаги на рабочую область.
  3. Соединить шаги ребрами и назначить им метаданные.
  4. Заполнить атрибуты MERGE_JOIN:

joinKey = "$s1(a);$s3#$m1(a);$m3"
joinType = "leftOuter"
transform =

function transform() {
    $out[0].s = $in[0].s1 + $in[1].m1;
    $out[0].m = $in[0].s3 + $in[1].m3;
    return ALL;
}

slaveDuplicates = "false"
equalNull = "true"

  1. Данные с двух потоков будут объединены.

CROSS_JOIN

CROSS_JOIN создает декартово произведение записей из подключенных входных портов.

Каждая строка из первого порта соединяется с каждой строкой из последующих портов, в результате получаются все возможные сочетания значений со всех портов. Возможно преобразование данных с помощью атрибута transform.

CROSS_JOIN автоматически передаёт метаданные на выходной порт в соответствии с метаданными на его входных портах.

Заметка: при обработке очень большого количества записей, на жёстком диске могут быть созданы временные файлы с обрабатываемыми записями. Это предотвращает чрезмерное использование оперативной памяти.

Порты CROSS_JOIN:

Тип портаНомерОбязательныйОписаниеМетаданные
Input0даГлавный входной портлюбые
1-nнетВедомый входной порт(ы)
Output0даДля выходных записей

Атрибуты CROSS_JOIN:

АтрибутОбязательныйОписаниеВозможные значения
transform

нет

Функция преобразования данных, определённая в графе

<attr name="transform"><![CDATA[
    function transform() {
        $out[0].id = $in[1].id;
        $out[0].name = $in[1].name;
        $out[0].test_data_id = $in[0].test_data_id;
        $out[0].tmstmp = $in[0].tmstmp;
        $out[0].category_id = $in[0].category_id;

        return ALL;
    }
    ]]>
</attr>

Пример.

Создать таблицу со всеми возможными сочетаниями игроков в бильярд из двух команд:

Игроки первой команды:

Вася
Маша
Никита

Игроки второй команды:

Алёна
Петя
Лиза

Решение: Нужно только подключить источники данных к портам компонента CROSS_JOIN. Настройка атрибутов компонента не требуется.

В результате получится такой набор пар игроков в бильярд:

Вася | Алёна
Вася | Петя
Вася | Лиза
Маша | Алёна
Маша | Петя
Маша | Лиза
Никита | Алёна
Никита | Петя
Никита | Лиза

Заметка: Ребро, по которому передаётся наибольшее количество записей, должно быть подключено к первому входному порту.

DBJOIN

DBJOIN получает данные через один входной порт и объединяет их с данными из таблицы базы данных. Эти два источника данных могут иметь разную структуру метаданных.

Не требует сортировки входных данных и работает очень быстро, поскольку данные обрабатываются в памяти.

После объединения данные отправляются на первый выходной порт. Второй выходной порт может использоваться для вывода несовпадающих по ключу записей из основного потока.

Поток передающий данные через первый входной порт, называются основным, а поток данных из базы называется подчинённым. Его данные считаются поступившими через виртуальный входной порт. Каждая основная запись сопоставляется с подчинённой записью по одному или нескольким полям, называемым ключом соединения.

Выходные данные создаются путем применения преобразования, которое сопоставляет объединенные входные данные с выходными.

Порты DBJOIN:

Тип портаНомерОбязательныйОписаниеМетаданные
Input0даГлавный входной портЛюбые
1 (виртуальный)даПодчинённый входной порт
Output0даВыходной порт для объединенных данных
1нетВыходной порт для необъединённых данныхКак на Input 0

Атрибуты DBJOIN:

АтрибутОбязательныйОписаниеВозможные значения
joinKeyдаКлюч, по которому объединяются входящие потоки данных. Если полей ключа несколько - они должны быть записаны через точку с запятой. Перед именем поля должен стоять знак доллара `$`.

$schemaName;$tableName

joinTypeнетТип объединения. Бывает "inner"(по умолчанию) и "leftOuter"joinType="leftOuter"
dbConnectionдаИдентификатор соединения с БД, который будет использоваться в качестве ресурса подчинённых записей.conn0
sqlQueryдаSQL-запрос. В условии WHERE нужно использовать плейсхолдер '?' для подстановки значения ключа (если ключ составной, используйте плейсхолдер для каждого поля в WHERE).

        select c.ordinal_position
        from information_schema.tables t
            join information_schema.columns c on c.table_name=t.table_name
                                              and c.table_schema=t.table_schema
        where lower(t.table_schema)=lower(?)
            and lower(t.table_name)=lower(?)
            and lower(c.column_name)=lower(?)

urlдаИмя внешнего файла, включая путь, содержащий SQL-запрос.

url="${QUERY_DIR}"

transformдаФункция преобразования
function transform() {
    $out[0].customer_id = $in[0].person_number;
    $out[1].customer = $in[0].person_name;
return ALL;
}

cacheSizeМаксимальное количество записей с разными значениями ключей, которые можно сохранить в памяти.

cacheSize="100" по умолчанию

charsetКодировка файла, в котором хранится алгоритм преобразования.

charset="UTF-8" по умолчанию

Ключ соединения

Ключ соединения — это последовательность имен полей из основного источника данных, отделенных друг от друга точкой с запятой. Ключ можно определить в редакторе шага. Порядок имен полей должен соответствовать порядку ключевых полей таблицы базы данных (и их типам данных). Подчинённая часть ключа соединения должна быть определена в атрибуте sqlQuery.

$first_name;$last_name

Это поля, которые служат для объединения основных записей с подчинёнными записями. SQL-запрос должен содержать выражение, которое может выглядеть следующим образом:

... where fname=? and lname=?

Значение first_name будет подставлено на место первого знака вопроса в этом условии, а last_name - на место второго. Сначала будет произведён поиск совпадений по joinKey в кеш-памяти, если подходящих записей не обнаружится, то данные будут запрошены из базы данных, иначе - найденная запись сразу отправится для преобразования в функцию transform.

Преобразование

Преобразование в DBJOIN позволяет определить способ сопоставления данных, с помощью которого записи буду отправлены на первый выходной порт. Несоединенные записи из основного потока, отправляемые на второй выходной порт, не могут быть изменены в рамках преобразования DBJOIN.

Заметка: Если преобразование указано во внешнем файле, рекомендуется явно указать кодировку файла в артибуте charset.

Заметка:

  • при получении более одной записи из базы в лог будет выведено предупреждение "read more than one record".
  • при автоматическом увеличении рамера кеша для обработки данных - "riched cache size".

Пример. Соединение записей из двух источников.

  1. Объединим записи из двух баз. Используем DB_READER для чтения из базы postgres и DBJOIN для чтения из firebird и объединения потоков по ключу.

Запрос для DB_READER:

sqlQuery = "select bigintcolumn, booleancolumn, charcolumn, smallintcolumn, textcolumn from onebridge."million_row" order by bigintcolumn limit 100"

Атрибуты для DBJOIN:

sqlQuery = "select FIRST 100 bigintcolumn, booleancolumn, charcolumn, smallintcolumn, textcolumn from MILLION_ROW WHERE bigintcolumn = ?"

Объединённые данные можно вывести на первый выходной порт DBJOIN, а не обьединенные данные с главного входного порта - на второй порт.

Для управления заданиями

Шаги из группы управления заданиями позволяют запускать другие графы, отслеживать и при необходимости прерывать задания.

Реализованы следующие шаги для управления заданиями:

EXECUTE_GRAPH

Шаг EXECUTE_GRAPH запускает граф с определенными настройками, ожидает завершения графа и предоставляет результаты и детали выполнения на выходные порты.

Порты EXECUTE_GRAPH:

Тип портаНомерОбязательныйОписаниеМетаданные
Input0нетВходные записи с настройками выполнения графа.Любые
Output0нетИнформация об успешном выполнении задания.
1нетИнформация о неудачном выполнении задания.

Атрибуты EXECUTE_GRAPH:

АтрибутОбязательныйОписаниеВозможные значения
jobURLдаПуть к исполняемому графу. В этом атрибуте можно указать только один граф. Значение может быть переопределено значением из входного потока, см. атрибут «inputMapping».

jobURL="${GRAPH_DIR}/fldr/fldr/work.grf"

orderOutputнетПараметр указывает, сохранится ли порядок дочерних графов на выходе потока данных из шага. При 'true' - выходные данные подаются в соответствии с порядком запуска дочерних графов. При 'false', результаты выполнения передаются на выходной порт по мере выполнения.

orderOutput="true" по умолчанию

concurrentRunsLimitнетКоличество исполняемых параллельно дочерних графов.

concurrentRunsLimit="1" по умолчанию

inputMappingнетМаппинг входных данных определяет, как данные из входящего потока переопределяют значение jobURL, значение передаваемых в вызываемый граф параметров и словарей.

порт $out[0] - для переопределения значения jobURL;
порт $out[1] - для передачи значений параметров во внутренний граф;
порт $out[2] - для передачи значений словаря во внутренний граф;


function transform() {
    $out[0].jobURL = "inner-graph.grf"; //переопределение значения атрибута jobURL (имя вызываемого графа)
    $out[1].data_out = "data-out.txt"; // передача значения параметра в вызываемый граф
    $out[1].currency = '30'; // передача значения параметра в вызываемый граф
    $out[2].dct = dictionary.d1; //передача значения словаря в вызываемый граф

    return ALL;
}
outputMappingнетМаппинг выходных данных сопоставляет результаты успешного выполнения графа с метаданными первого выходного порта.

порт $in[0] - для передачи записей из внутреннего графа.
порт $in[1] - для передачи информации о результате выполнения внутреннего графа (runId, originalJobURL, startTime, endTime, status).
порт $in[2] - для передачи записей из словаря внутреннего графа (dictionaryName).


function transform() {
    $out[0].boo = $in[0].boo;
    $out[0].runId = $in[1].runId.toString();
    $out[0].originalJobURL = $in[1].originalJobURL.toString();
    $out[0].startTime = $in[1].startTime.toString();
    $out[0].endTime = $in[1].endTime.toString();
    $out[0].status = $in[1].status.toString();
    $out[0].dct1 = $in[2].dct1;

    return ALL;
}
errorMappingнетМаппинг ошибок отображает результаты неудачных запусков графов на второй выходной порт.

function transform() {
        $out[1].status = $in[1].status.toString();

        return ALL;
}

Подробности хода выполнения

Компонент считывает входную запись, выполняет граф на основе значений входящих данных, ждет завершения графа и отправляет результаты на соответствующий порт. Результаты успешного запуска графа отправляются на первый выходной порт. Результаты неудачного запуска отправляются на второй выходной порт (порт ошибки).

Если запуск графа прошел успешно, компонент продолжает обработку следующих входных записей. В противном случае компонент прекращает выполнение других графов, и с этого момента все входящие записи игнорируются, а информация об игнорируемых записях отправляется на порт вывода ошибок.

Подключенные и отключенные порты

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

В случае, если первый выходной порт не подключен, компонент не выводит результаты выполнения графа.

Если второй выходной порт (порт ошибки) не подключен, первый граф с ошибкой приведет к прерыванию родительского задания.

Конфигурация компонента

Для запуска графа с помощью шага EXECUTE_GRAPH необходимо указать местоположение исполняемого графа в атрибуте jobURL.

Большинство настроек выполнения можно указать в шаге с помощью атрибутов компонента, описанных ниже.

Настройки выполнения графа можно изменять для каждого запуска на основе данных из входящего потока в атрибуте inputMapping.

Типы выполнения графа

EXECUTE_GRAPH поддерживает синхронное (последовательное) и асинхронное (параллельное) выполнение графов.

Для управления синхронностью выполнения используйте следующие атрибуты шага:

  • concurrentRunsLimit - целое число, обозначающее сколько графов одновременно могут выполняться. По умолчанию значение равно 1 и дочерние графы выполняются параллельно, но если установить большее значение, то графы смогут выполняться асинхронно.
  • orderOutput - указывает порядок информации о дочерних графах, выдаваемой на выходной порт шага ExecuteGraph. По-умолчанию установлено значение true и выходные данные подаются в соответствии с порядком запуска дочерних графов. При false, результаты выполнения будут передаваться на выходной порт по мере выполнения дочерних графов.

Мапинг входных данных

Атрибут inputMapping позволяет переопределить настройки шага на основе данных из входящего потока.

Маппинг входных данных — это преобразование, которое выполняется для каждой входной записи. С помощью inputMapping можно переопределить атрибут jobURL и передать в исполняемый граф значения его атрибутов и записи словаря.

На первый выходной порт можно подать значение для переопределения атрибута jobURL, а на второй выходной порт - параметры для исполняемого графа.

Можно задавать не только явно определённые публичные параметры, но и определять новые параметры, они будут доступны внутри графа по аналогии с такими встроенными параметрами как runId.

Тип портаНомерОбязательныйОписаниеПример
Output0нетДля переопределения пути к исполняемому графу
$out[0].jobURL = "newJob.grf" 
1Для передачи параметров в исполняемый граф
$out[1].graphParameterName = "<some value>"
2Для передачи записей в словарь исполняемого графа
$out[2].dictionaryName = "<some value>"

Маппинг выходных данных

outputMapping — это преобразование, которое используется для заполнения потока, передаваемого в первый выходной порт шага EXECUTE_GRAPH. Этот маппинг используется для вывода данных при успешном выполнении графа.

Данные, предоставляемые на первый выходной порт EXECUTE_GRAPH с помощью outputMapping описаны в таблице ниже. Первый выходной порт задействуется только если статус графа $in[1].status = "SUCCEEDED", в противном случае будет вызван errortMapping и данные пойдут на второй выходной порт.

Тип портаНомерОбязательныйОписаниеПример
Output0нетДля входящего потока записей

$in[0] = $in[0] в inputMapping

1Уникальный идентификатор запуска графа

$in[1].runId

Путь к исполняемому графу

$in[1].originalJobURL

Время запуска графа

$in[1].startTime

Время завершения графа

$in[1].endTime

Окончательный статус выполнения графа, один из { SUCCEEDED, FAILED }

$in[1].status

2Для передачи записей из словаря исполняемого графа

$out[2].dictionaryName

Маппинг ошибок

errorMapping — это тоже трансформация. Она используется для вывода ошибок. Данные, которые можно отправить через errorMapping аналогичны описанным в таблице в outputMapping.

Маппинг ошибок используется в том случае, если внутренний граф завершился неудачно - со статусом $in[1].status = "FAILED" - тогда вместо первого заполняется второй выходной порт шага EXECUTE_GRAPH.

Если маппинг ошибок не определен, а во внутреннем графе произошла ошибка - родительский граф не сможет ее обработать и упадёт.

Пример передачи параметров через словарь

Для передачи данных из основного графа во внутренний через словарь, необходимо использовать второй выходной порт в inputMapping. Для передачи значений из словаря внутреннего графа в основной - второй входной порт в outputMapping.

Задание: Передать значение в словарь внутреннего графа, изменить его, получить изменённое значение и вывести его в лог.

Решение: Чтобы запустить из графа другой граф - используйте шаг EXECUTE_GRAPH. Чтобы передать значения в вызываемый граф - заполните атрибут inputMapping, присвоив начальное значение записи словаря вызываемого графа. Изменённое внутри вызываемого графа значение словаря можно получчить в основном графе через outputMapping шага EXECUTE_GRAPH.

В inputMapping шага execgrf через второй выходной порт присваиваем значение 11 записи словаря с именем foo, определённого во внутреннем графе. Значение словаря передаётся во внутренний граф. В outputMapping получаем через второй входной порт изменённое значение записи этого словаря.

    <Node id="execgrf" guiX="386" guiY="49" guiName="exec" type="EXECUTE_GRAPH" jobURL="dict_inner3.grf">
      <attr name="inputMapping"><![CDATA[ 
                function transform() {
                    $out[2].foo = 11;
                    return ALL;
                }
                ]]></attr>
      <attr name="outputMapping"><![CDATA[ 
                function transform() {
                    $out[0].foo = $in[2].foo;
                    return ALL;
                }
                ]]></attr>
    </Node>

Объявление словаря в теге <Global> во внутреннем графе:

<Dictionary>
    <Entry dictval.value="1" name="foo" input="true" output="true" type="integer" />
</Dictionary>

Переопределение значения записи словаря foo в датагенераторе внутреннего графа:

    <Node id="datagen1" guiX="98" guiY="57" guiName="datagen1" type="DATA_GENERATOR" recordsNumber="1">
      <attr name="generate"><![CDATA[
                function generate() {
                    $out[0].foo = dictionary.foo;
                    dictionary.foo = 43;
                    return ALL;
                }
                ]]></attr>
    </Node>

GET_GOB_INPUT

Шаг GET_GOB_INPUT извлекает значения параметров графа и отправляет их в выходной порт. Компонент создает одну выходную запись, которая заполняется содержимым словаря или параметрами графа.

Порты GET_GOB_INPUT:

Тип портаНомерОбязательныйОписаниеМетаданные
Output0даДля записей, содержащих входные данные для графа.Любые

Атрибуты GET_GOB_INPUT:

АтрибутОбязательныйОписаниеВозможные значения
mappingдаМаппинг заполняет выходную запись словаря. Входные записи словаря и параметры графа являются естественными значениями для маппинга.
function transform() {
    $out[0].b = dictionary.in1;
return ALL;
}

Пример. Прочитать значения словаря и параметра.

Например, нужно прочитать значение словаря "dct1" и параметра "prm1" и передать их дальше для обработки.

Для этого понадобится шаг GET_GOB_INPUT и TRASH для вывода данных и метаданные для передачи данных.

В GET_GOB_INPUT нужно заполнить значение атрибута "mapping" следующим присвоением:

function transform() {
	$out[0].dct = dictionary.dct1;
	$out[0].prm = "${prm1}";
return ALL;
}

Значения словаря и параметра будут поданы на выходной порт шага GET_GOB_INPUT.

SET_GOB_OUTPUT

Шаг SET_GOB_OUTPUT заполняет значения словаря входящими данными из потока. Выходные записи словаря заполняются в соответствии с маппингом. Первая входная запись устанавливает значения записей словаря, а последующие входные записи переопределяют существующие значения.

Порты SET_GOB_OUTPUT:

Тип портаНомерОбязательныйОписаниеМетаданные
Intput0дадля внесения записей в словарь.Любые

Атрибуты SET_GOB_OUTPUT:

АтрибутОбязательныйОписаниеВозможные значения
mappingдаОпределяет сопоставление метаданных входной записи с выходными записями словаря.
function transform() {
    dictionary.in2 = $in[0].b;
return ALL;
}

Пример. Присвоить значения из входного потока словарю.

Например, нужно прочитать значение поля "word" и присвоить его словарю "dct1".

Для этого понадобится шаг FLAT_FILE_WRITER, чтобы передать значение поля, SET_GOB_OUTPUT для установки значения словаря. Для проверки можно использовать GET_GOB_INPUT и TRASH для вывода данных словаря на ребро.

В SET_GOB_OUTPUT нужно заполнить значение атрибута "mapping" следующим присвоением:

function transform() {
	dictionary.dct1 = $in[0].word;
return ALL;
}

Значение поля "word" будет присвоено словарю с именем "dct1".

SUCCESS

SUCCESS — это успешная конечная точка рабочего процесса. Записи, поступающие в компонент, больше не обрабатываются — они считаются успешно обработанными в рамках текущего запуска. У шага только один входной порт. Шаг не содержит атрибутов.

Порты SUCCESS:

Тип портаНомерОбязательныйОписаниеМетаданные
Input0даДля входных записейЛюбые

FAIL

FAIL прерывает выполнение задания как только в него попадают записи. Родительское задание останавливается со статусом Не выполнено.

Порты FAIL:

Тип портаНомерОбязательныйОписаниеМетаданные
Input0даДля входных записейЛюбые

EXECUTE_SCRIPT

Шаг EXECUTE_SCRIPT запускает указанный скрипт с помощью выбранного интерпретатора.

Если к входному порту не подключено ребро, шаг запускает скрипт только один раз. В этом случае создается одна выходная запись.

Когда на входной порт поступают записи, выполняется одно выполнение скрипта для каждой записи и создается одна выходная запись для каждого выполнения скрипта.

Если скрипт выполнен успешно, шаг продолжает обработку следующих входных записей. В противном случае шаг прекращает выполнение скрипта и завершается с ошибкой.

Порты EXECUTE_SCRIPT:

Тип портаНомерОбязательныйОписаниеМетаданные
Input0нетПараметры запуска скрипта.Любые
Output0нетРезультаты выполнения скрипта.Любые

Атрибуты EXECUTE_SCRIPT:

АтрибутОбязательныйОписаниеВозможные значения
scriptнетКод скрипта, который будет выполнен.
scriptURLнетURL-адрес скрипта, который будет выполнен.scriptURL="./folder/data/stage/script.exe"
scriptCharsetнетКодировка символов, используемая в скрипте.scriptCharset="UTF-8 "
interpreterдаИспользуемый интерпретатор.interpreter="сmd"
workingDirectoryнетРабочий каталог исполняемого скрипта. Все относительные пути, используемые внутри скрипта, будут интерпретироваться относительно этого каталога. workingDirectory="./data-tmp/stage/ftpClearHistory/"
inputMappingнетЗадаёт параметры выполнения скрипта. Можно переопределить script, scriptURL, interpreter, workingDirectory.

<attr name="inputMapping">
    <![CDATA[
        function transform() {
            $out[0].script = 'zip -r '+fileNameWithoutExtension+'.zip '+fileName+ ' --password ${ARCHIVE_PASSWORD}';
        return ALL;
        }
    ]]>
</attr>

outputMappingнетСопоставляет результаты успешного выполнения скрипта с метаданными на выходном порте.

<attr name="outputMapping">
    <![CDATA[
        function transform() {
            $out[0] = $in[1];	
        return ALL;
        }
    ]]>
</attr>

Мапинг входных данных

Атрибут inputMapping позволяет переопределить настройки шага на основе данных из входящего потока.

Параметры, которые можно переопределить в inputMapping:

  • script,
  • scriptURL,
  • scriptCharset,
  • interpreter,
  • workingDirectory.

Маппинг выходных данных

outputMapping — это преобразование, которое используется для заполнения потока, передаваемого в нулевой выходной порт шага EXECUTE_SCRIPT. Этот маппинг используется для вывода данных при успешном выполнении графа.

Данные, которые шаг может подать на выход:

  • std_out,
  • err_out,
  • exit_value,
  • err_exception.

Пример. Выполнение скрипта, указанного в файле.

Нужно запустить скрипт и вывести результат его работы в файл. Для этого:

  1. Поместить шаг EXECUTE_SCRIPT на рабочую панель Дизайнера.
  2. Заполнить атрибуты EXECUTE_SCRIPT в редакторе шага:
АтрибутЗначение
scriptURLsome_directory_name/scriptURL.sh
interpretersh
outputMapping
function transform() {

$out[0].stdOut = $in[1].stdOut;
$out[0].errOut = $in[1].errOut;
$out[0].exitValue = $in[1].exitValue;
$out[0].errException = $in[1].errException;

return ALL;
}
  1. Поместить на рабочую область шаг FLAT_FILE_WRITER.
  2. Заполнить атрибуты FLAT_FILE_WRITER в редакторе шага:
АтрибутЗначение
fileURLdataout_dir/file_name.txt
  1. Соединить шаги ребром с метаданными:
Имя поляТип данных
stdOutstring
errOutstring
exitValuestring
errExceptionstring

Используемый скрипт:

echo 'scriptURL'

После запуска графа в файл "dataout_dir/file_name.txt" запишется следующее:

Имя поляЗначение
stdOutscriptURL
errOut
exitValueexit status: 0
errException

Другие

Шаги этой группы служат для выполнения множества разнородных задач.

NOTE

NOTE (примечание, заметка) - позволяют пользователю вводить необходимую информацию непосредственно в граф. Примечания могут служить документацией к конкретному графу. Также заметки могут служить контейнерами для компонентов. Если вы перемещаете заметку, вы также перемещаете компоненты внутри заметки. Если вы вводите какой-либо параметр в заметке, этот параметр не заменяется его значением. У заметок нет портов и атрибутов, так как они являются не рабочей частью графа, а только вспомогательным элементом.

Вы можете поместить заметку на граф из Списка компонентов: перетащите заметку из Списка и поместите ее в Рабочую панель.

Заметка в графе

Заметка в графе

DBEXECUTE

DBEXECUTE выполняет указанные SQL-инструкции для базы данных, подключенной с помощью драйвера ODBC. Он может выполнять запросы, транзакции, вызывать хранимые процедуры или функции.

Входные параметры могут быть получены через первый входной порт, а выходные параметры или набор результатов отправляются в первый выходной порт. Информация об ошибке может быть отправлена на второй выходной порт.

Порты DBEXECUTE:

Тип портаНомерОбязательныйОписаниеМетаданные
Input0нет*Входные записи для SQL запросаЛюбые
Output0нет**Результат выполнения Любые
1нетОшибки выполненияНа основе входных метаданных

* Входной порт должен быть подключен, если указан атрибут 'inParameters' или если через входной порт принимается весь SQL-запрос.

** Выходной порт должен быть подключен, если указаны выходные параметры запроса в 'outParameters' или атрибут 'outputFields'.

Атрибуты DBEXECUTE:

АтрибутОбязательныйОписаниеВозможные значения
dbConnectionдаИдентификатор соединения с БД, которое будет использоваться.
dbConnection= "postgres://${DB_USR}:${USR_PWD}@${HOST}:${PORT}/${DB_NAME}"
sqlQueryдаSQL-запрос. Содержит операторы SQL, которые следует выполнить для базы данных.

Если запрос состоит из нескольких операторов, они должны быть отделены друг от друга указанным разделителем операторов SQL. Операторы будут выполняться один за другим.

<Attr name="sqlQuery">
    <![CDATA[
        CREATE TABLE IF NOT EXISTS ${TABLE_NAME} (id INT,surname TEXT,name TEXT);
        TRUNCATE TABLE ${TABLE_NAME};
        SELECT * FROM ${TABLE_NAME};
    ]]> 
</Attr>
inParametersнетИспользуется при вызове хранимой процедуры/функции с входными параметрами. Это последовательность следующего типа: 1:=$inputField1;…​;n:=$inputFieldN. Значение каждого указанного поля ввода сопоставляется с соответствующим параметром (позиция которого в SQL-запросе равна указанному числу).inParameters="1:=$srgKey;"
outParametersнетИспользуется при вызове хранимой процедуры или функции с выходными параметрами или возвращаемым значением. Это последовательность следующего типа: 1:=$outputField1;…​;n:=$outputFieldN. Значение каждого выходного параметра (определяемого его позицией в SQL-запросе) будет записано в указанное поле.outParameters="2:=$customer_name;"
outputFieldsнетЕсли хранимая процедура или функция возвращает набор данных, ее выходные данные будут сопоставлены с заданными полями вывода. Атрибут выражается как последовательность имен выходных полей, отделенных друг от друга точкой с запятой.outputFields="1:=$square;2:=$cube"
inTransactionнетУказывает, должны ли выполняться инструкции в транзакции. Применяется в случае, если база данных поддерживает транзакции.SET (default) | ONE | ALL | NEVER_COMMIT
urlнетСодержит либо имя внешнего файла, содержащего SQL-запрос, либо строку, которая используется для чтения из входного порта.
url="port:$0.script:discrete"

или

url="port:$0.fieldname:source"
charsetнетКодировка внешнего файла, указанного в атрибуте urlcharset="UTF-8"

Пример. Очистка таблицы.

Шаг DB_EXECUTE можно использовать, например, для очистки таблицы перед заполнением её с помощью другого шага.

  1. Переместите DB_EXECUTE с палитры компонентов на рабочую область дизайнера
  2. Заполните его атрибуты:

АтрибутЗначение
dbConnectionconn0 (имя соединения)
sqlQuery

truncate table services;

Таблица services будет очищена.

LIST_FILES

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

Порты LIST_FILES:

Тип портаНомерОбязательныйОписаниеМетаданные
Input0нетдля входных записей.Любые
Output0дадля выходных записей, по одной на каждую запись из целевого каталога.Любые

Атрибуты LIST_FILES:

АтрибутОбязательныйОписаниеВозможные значения
fileURLнетПуть к файлу или каталогу, который должен быть обработан.fileURL="${GRAPH_DIR}/bl/Megapolis/dic/list.grf"
recursiveнетПеречислять подкаталоги рекурсивно. По умолчанию 'false'.recursive='true'
inputMappingнетОпределяет сопоставление входных записей с атрибутами компонента. Позволяет переопределить fileURL и recursive.

<attr name="inputMapping">
    <![CDATA[
        function transform() {
            $out[0].fileURL = "${DATATMP_DIR}";
            return ALL;
        }
    ]]>
</attr>

outputMappingнетОпределяет отображение результатов на выходном порте.

<attr name="outputMapping">
    <![CDATA[
        function transform() {
            $out[0].url = $in[1].URL;
            $out[0].fileName = $in[1].name;
            $out[0].lastModified = $in[1].lastModified;
        
            return ALL;
        }
    ]]>
</attr>

INPUT_TABLE

Шаг INPUT_TABLE позволяет работать с табличными данными в виде строки с разделителями.

Порты INPUT_TABLE:

Тип портаНомерОбязательныйОписаниеМетаданные
Output0дадля распарсенных записей.Любые

Атрибуты INPUT_TABLE:

АтрибутОбязательныйОписаниеВозможные значения
dataнетТабличные данные в виде строки с разделителями.
<attr name="data">
  <![CDATA[ 
    field1,field2,field3 
    field1,field2,field3
  ]]> 
</attr>

В следующем примере данные вносятся через шаг INPUT_TABLE, сортируются и выводятся в треш:


<Graph>
  <Global>
    <Metadata id="meta0" fileURL="allTypes.fmt"/>
    <Metadata id="meta1" fileURL="simpleTypes.fmt"/>
  </Global>
  <Phase number="0">

    <Node id="InputTable0" guiX="300" guiY="83" guiName="input_table" type="INPUT_TABLE">
        <attr name="data"><![CDATA[
            42.12,strrrr
            56.62,strttt]]>
        </attr>
    </Node>
    <Node id="Sort0" guiX="467" guiY="83" guiName="Sort" type="EXT_SORT" sortKey="field2(a)" sortInMemory="false">
    </Node>
    <Node id="Trash0" guiX="633" guiY="83" guiName="Trash" type="TRASH" debugOutput="true">
    </Node>
    <!--<Edge id="Edge2" fromNode="DataGenerator0:0" toNode="InputTable0:0" metadata="meta1"/>-->
    <Edge id="Edge1" fromNode="InputTable0:0" toNode="Sort0:0" metadata="meta1"/>
    <Edge id="Edge0" fromNode="Sort0:0" toNode="Trash0:0" metadata="meta1"/>
  </Phase>
</Graph>

HTTP_CONNECTOR

HTTP_CONNECTOR отправляет запросы к указанному серверу и получает ответы. Ответ может быть отправлен на выходной порт или сохранён в указанном файле.

Порты HTTP_CONNECTOR:

Тип портаНомерОбязательныйОписаниеМетаданные
Input0нетДля установки различных атрибутов шагаЛюбые
Output0Содержимое ответа, путь к файлу ответа, код состояния, атрибуты шага
1Подробности об ошибках

Атрибуты HTTP_CONNECTOR:

АтрибутОбязательныйОписаниеВозможные значения
urlнетURL-адрес сервера, к которому подключается коннектор. Поддерживаются протоколы HTTP и HTTPS.

https://catfact.ninja/fact

requestMethodнетМетод запроса.GET (по умолчанию) | POST | PUT | PATCH | DELETE | HEAD | OPTIONS | TRACE
additionalHttpHeadersнетДополнительные свойства запроса, который будет отправлен на сервер. Представляет собой последовательность пар ключ=значение, разделенных запятой.content-type=application/json
requestContentнетCодержимое запроса, определенное непосредственно в графе.
$out[0].requestContent = $in[0].xmlConfig;
inputFileURLнетURL-адрес загружаемого файла.
outputFileURLнетURL файла, в который записывается ответ на запрос.
appendOutputнетПо умолчанию любой новый ответ перезаписывает старый. Если вы переключите этот атрибут на true, новый ответ будет добавлен к старым. Применяется только к выходным файлам.
inputMappingнетСопоставление входных данных. Позволяет передавать значения атрибутов шага, сопоставляя их значения с данными из входного порта. Использование атрибута inputMapping устанавливает остальные входные атрибуты в их дефолтные значения, в связи с этим, при использовании входного маппинга стоит задавать через него сразу все значения атрибутов.
function transform() {     
$out[0].url = $in[1].url;
$out[0].requestMethod = $in[1].requestMethod;

return ALL;
}
outputMappingнетСопоставление выходных данных. Позволяет сопоставить данные ответа на запрос (например, содержимое тела ответа, код состояния и т. д.) с метаданными выходного порта.
function transform() { 
$out[0].content = $in[1].content;
$out[0].statusCode = $in[1].statusCode;
$out[0].rawHeaders = $in[1].rawHeaders;

return ALL;
}
errorMappingнетМаппинг ошибок. Позволяет сопоставить сообщения об ошибке с метаданными выходного порта.
function transform() { 
$out[1].errorMesage = $in[1].errorMesageж;

return ALL;
}
redirectErrorOutputнетПозволяет перенаправить сведения об ошибке на нулевой выходной порт.redirectErrorOutput="false" по умолчанию
timeoutнетКак долго шаг ждет ответа. Если он не получает ответ в течение указанного срока, выполнение шага завершается неудачей. По умолчанию HTTP_CONNECTOR имеет тайм-аут в одну минуту. Тайм-аут указывается в миллисекундах.timeout="60000"
retryCountнетКоличество раз, которое нужно повторить запрос в случае сбоя. Сбой означает то же самое, что и использование компонентом порта ошибки. Компонент считает сбой, если он не может обработать запрос/ответ. Если он обрабатывает запрос и получает ответ с кодом статуса ошибки (например, 500), это не является сбоем.retryCount="6"
retryDelayнетКак долго шаг должен ждать перед повторной попыткой запроса. Если retryCount не нулевой, шаг будет ждать дополнительное время перед повторной отправкой запроса. Значение атрибута — это список целых чисел, разделенных запятой. Задержка повтора указывается в секундах. Если количество повторных попыток превышает размер списка, то используется последняя задержка в списке.retryDelay="4,2,5"
dnsResolverнетДля явного указания адреса сервера. Установите порт ":0", чтобы использовать обычный порт для указанной схемы (например, 80 для http). Порты в самом URL всегда будут использоваться вместо порта в переопределенном адресе.dev.allbridge.ru=127.0.0.1:0,127.0.0.1:443; another.domain.ru=192.168.0.0:0

Маппинг входных данных

В атрибуте inputMapping можно указать, какие поля из входной записи следует сопоставить с атрибутами шага.

  • URL — адрес, по которому будет отправлен запрос.
  • requestMethod — метод, который будет использован при отправке запроса.
  • additionalHttpHeaders - дополнительные заголовки запроса.
  • requestContent — содержимое отправляемого запроса в виде строки.
  • inputFileUrl — адрес файла, котрый нужно отправить, относительно проекта.
  • outputFileURL - адрес файла в который записать ответ.
  • appendOutput - применяется, если указан outputFileURL. При appendOutput=true новый ответ будет дозаписан в выходной файл без очистки файла от предыдущего содержимого.

Пример заполнения преобразования для маппинга входных данных:

function transform() { 
$out[0].requestContent = $in[1].requestContent;

return ALL;
}

Маппинг выходных данных

С помощью атрибута outputMapping на первый выходной порт можно отправить такие данные:

  • Результат — предоставляет данные о результате запроса. К нему относятся:
    • content — содержимое HTTP-ответа (response body) в виде строки. Это поле будет иметь значение null, если ответ записывается в файл.
    • outputFilePath - путь к файлу, в который записан ответ. Будет null, если ответ не записывается в файл.
    • statusCode — код состояния HTTP ответа.
    • rawHeaders — заголовки (response headers) ответа.
    • errorMessage — сообщение об ошибке в случае, если вывод ошибки перенаправляется на стандартный порт вывода.

Пример заполнения преобразования для маппинга выходных данных:

function transform() { 
$out[0].content = $in[1].content;
$out[0].outputFilePath = $in[1].outputFilePath;
$out[0].statusCode = $in[1].statusCode;
$out[0].rawHeaders = $in[1].rawHeaders;
$out[0].errorMesage = $in[1].errorMesage;

return ALL;
}

Маппинг ошибок

С помощью атрибута errorMapping можно вывести сооющение об ошибке на выходной порт HTTP_CONNECTOR. Поведение очень похоже на отображение выходных данных, но данные при этом выводятся на первый выходной порт шага, вместо нулевого.

Для того, чтобы потенциальная ошибка была выведена на порт ошибки, нужно указать для атрибута redirectErrorOutput значение false. При redirectErrorOutput=true ошибка будет выведена на нулевой выходной порт, вместе с остальными выходными данными шага.

Если в ответ на запрос приходит ошибка, а errorMapping не заполнен и redirectErrorOutput=false, то граф не сможет её обработать и упадет.

Пример заполнения преобразования для маппинга ошибок:

function transform() { 
$out[1].errorMesage = $in[1].errorMesageж;

return ALL;
}

Пример 1. Скачать Web-страницу

Загрузите содержимое веб-страницы modernsolution.ru/onebridge с помощью HTTP_CONNECTOR. Сохраните результат в файл для дальнейшей обработки.

Решение

Используйте атрибуты url, requestMethod и outputFileURL.

Загруженная страница будет сохранена в файле result.html в каталоге ${DATAOUT_DIR}.

АтрибутЗначение
url

https://modernsolution.ru/onebridge/

requestMethodget
outputFileURL${DATAOUT_DIR}/result.html

Пример 2. Получение токенов доступа для Onebridge и запуск задания с помощью HTTP_CONNECTOR

Цель данного примера - показать схему авторизации с получением токенов через api для запуска в работу задания Onebridge.

Для того чтобы запустить задание в работу, нужно быть авторизованным пользователем с набором привилегий для запуска. Предположим, все нужные привилегии пользователю выданы, осталось получить токен для авторизованной отправки запроса на запуск задания.

Чтобы получить токены, нужно отправить запрос на аутентификацию с помощью того же HTTP_CONNECTOR:

  1. Переместите на рабочую область Дизайнера шаг HTTP_CONNECTOR из палитры компонентов.
  2. Заполните атрибуты шага с помощью редактора шага:

АтрибутЗначение
url

https://onebridge-dev.dev.allbridge.ru/api/auth/login

requestMethodPOST
additionalHttpHeaderscontent-type=application/json
requestContent{"username": "${username}", "password":"${password}"}
outputMapping
function transform() {
$out[0].content = $in[1].content;
$out[0].outputFilePath = $in[1].outputFilePath;
$out[0].statusCode = $in[1].statusCode;
$out[0].rawHeaders = $in[1].rawHeaders;
$out[0].errorMessage = $in[1].errorMessage;

return ALL;
}
errorMapping
function transform() {
  $out[1].errorMessage = $in[1].errorMessage;

  return ALL;
}
redirectErrorOutputfalse
  1. Полученные токены нужно передать дальше в MAP через первый выходной порт. Для обработки ошибок заполните errorMapping и подключите ко второму выходному порту шаг TRASH.
  2. В MAP можно распарсить присланный в ответе на запрос json в две отдельных переменных следующим образом:
АтрибутЗначение
transform
function transform() {
  let { access_token, refresh_token } = JSON.parse($in[0].content);

  $out[0].access_token = access_token;
  $out[0].refresh_token = refresh_token;

  return ALL;
}
  1. Теперь нужно отправить авторизованный запрос на запуск задания, для этого используем новый HTTP_CONNECTOR, заполнив его атрибуты следующим образом:

АтрибутЗначение
url

https://onebridge-dev.dev.allbridge.ru/api/runs

requestMethodPOST
inputMapping
function transform() {
$out[0].additionalHttpHeaders = "content-type=application/json, authorization=Bearer " + $in[0].access_token;
$out[0].requestMethod = "post";
$out[0].requestContent = '{"job_file":"/ready-check/689_get_catfact.grf","params":[]}';

return ALL;
}
outputMapping
function transform() {
$out[0].content = $in[1].content;
$out[0].outputFilePath = $in[1].outputFilePath;
$out[0].statusCode = $in[1].statusCode;
$out[0].rawHeaders = $in[1].rawHeaders;
$out[0].errorMessage = $in[1].errorMessage;

return ALL;
}
errorMapping
function transform() {
  $out[1].errorMessage = $in[1].errorMessage;

  return ALL;
}
redirectErrorOutputfalse
  1. В случае успешного ответа на post-запрос для запуска задания должен прийти номер запущенного задания. Выведем его номер на первый выходной порт, например в файл с помощью FLAT_FILE_WRITER. Порт ошибок можно соединить с еще одним шагом TRASH.
  2. Для связи между шагами нужно описать метаданные и присвоить их соответствующим рёбрам.
    <Metadata id="meta0">
      <Record fieldDelimiter="," name="content" recordDelimiter="\n" type="delimited">
        <Field name="content" type="string"/>
        <Field name="outputFilePath" type="string"/>
        <Field name="statusCode" type="integer"/>
        <Field name="rawHeaders" type="string"/>
        <Field name="errorMessage" type="string"/>
      </Record>
    </Metadata>
    <Metadata id="meta1">
      <Record fieldDelimiter="," name="tokens" recordDelimiter="\n" type="delimited">
        <Field name="access_token" type="string"/>
        <Field name="refresh_token" type="string"/>
      </Record>
    </Metadata>
    <Metadata id="meta2">
      <Record fieldDelimiter="," name="error" recordDelimiter="\n" type="delimited">
        <Field name="errorMessage" type="string"/>
      </Record>
    </Metadata>
    <Metadata id="meta3">
      <Record fieldDelimiter="," name="tokens_and_input" recordDelimiter="\n" type="delimited">
        <Field name="access_token" type="string"/>
        <Field name="refresh_token" type="string"/>
        <Field name="url" type="string"/>
        <Field name="requestMethod" type="string"/>
        <Field name="additionalHttpHeaders" type="string"/>
        <Field name="requestContent" type="string"/>
      </Record>
    </Metadata>

Граф с распределенными метаданными будет выглядеть вот так:

Распределение метаданных на рёбрах графа

Распределение метаданных на рёбрах графа

После того как граф отработает, можно просмотреть содержимое ребер в датаинспекторе. В данном примере на последнем из ребер будет отображаться номер запущенного графа в поле "content".

Просмотр датаинспектора ребра отработавшего графа

Просмотр датаинспектора ребра отработавшего графа

Ролевая модель

Для разграничения прав пользователей в OneBridge существует система привилегий. Каждая привилегия определяет доступный с её помощью набор функциональности. Привилегии можно присвоить напрямую пользователю, а можно - сначала присвоить привилегию роли, а роль - пользователю.

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

Ниже описаны существующие привилегии, которые делятся на 7 групп.

Ресурсы

  • Просмотр - доступ к информации о сервере на странице Ресурсы: использование ресурсов, производительность, данные сервера.

Проекты

  • Просмотр и скачивание файлов и папок - просмотр списка проектов и их файлов в вебе и в Дизайнере, возможность скачивать данные проектов архивом.
  • Создание, изменение и удаление файлов и папок - возможность создавать, переименовывать, редактировать и удалять файлы, папки и проекты.

История выполнения

  • Чтение списка запусков, информации и статистики по запускам - просмотр списка запущенных заданий на странице Ресурсы и на Истории выполнения.
  • Чтение логов запусков - доступ ко вкладке Журнал на панели дополнительной информации на странице История выполнения в вебе и ко вкладке Log в Дизайнере.
  • Чтение данных на ребрах - доступ ко вкладке Инспектор заданий на панели доп. информации в веб приложении и к Datainspector в Дизайнере.
  • Запуск и остановка заданий - просмотр параметров задания, запуск задания в работу и его остановка.

Расписания

  • Просмотр - просмотр списка расписаний и информации о каждом из них на странице Расписания.
  • Создание, изменение и удаление - создание и модификация расписаний на соответствующей странице веб приложения, управление их статусами и удаление.

Обработчики событий

  • Просмотр - просмотр списка обработчиков событий и информации о каждом из них на странице Обработчики событий.
  • Создание, изменение и удаление - создание и модификация обработчиков событий на соответствующей странице веб приложения, управление их статусами и удаление.

Пользователи

  • Просмотр - просмотр списка пользователей на странице Пользователи, доступ к информации о пользователях, их привилегиях и ролях.
  • Создание и изменение - создание пользователя, изменение его статуса, сброс пароля, обновление привилегий и ролей на странице Пользователи в веб приложении.

Роли

  • Просмотр - просмотр списка ролей на странице Роли, информации о них, списка их привилегий и списка родительских ролей.
  • Создание, изменение и удаление - управление ролями на странице Роли в веб приложении: создание роли, обновление, удаление, изменение её привилегий и родительских ролей.

Маппинг привилегий и методов api

ГруппаПривилегияОписание метода APIМетод API
РесурсыПросмотрПросмотр использования ресурсовGET /utilization
Просмотр производительностиGET /performance
Просмотр информацииGET /info
ПроектыПросмотр и скачивание файлов и папокПросмотр дерева проектовGET /tree
Просмотр проектаGET /project
Просмотр директорииGET /directory
Просмотр файлаGET /file
Скачивание архива папкиGET /download
Создание, изменение и удаление файлов и папокСоздание проектаPOST /project
Переименование проектаPOST /project/rename
Удаление проектаDELETE /project
Создание директорииPOST /directory
Переименование директории/td>POST /directory/rename
Удаление директорииDELETE /directory
Создание файлаPOST /file
Переименование файлаPOST /file/rename
Обновление файлаPATCH /file
Удаление файлаDELETE /file
Шифрование параметровPOST /encrypt
История выполненияЧтение списка запусков, информации и статистики по запускамПросмотр запускаGET /runs/:id
Просмотр статистики запускаGET /runs/:id/stats
Просмотр содержимого заданияGET /runs/:id/job_content
Просмотр количества запусковGET /runs/num
Просмотр позиции запускаGET /runs/position
Список запусковGET /runs
Чтение логов запусковПросмотр логов запускаGET /runs/:id/log
Чтение данных на ребрахПросмотр данных на ребреGET /runs/:id/inspect
Запуск и остановка заданийПросмотр параметров заданияGET /job_params
Создание запускаPOST /runs
Остановка заданияPOST /runs/:id/abort
РасписанияПросмотрСписок расписанийGET /schedules
Просмотр информации о расписанииGET /schedules/:id
Создание, изменение и удалениеСоздание расписанияPOST /schedules
Переключение расписанияPOST /schedules/toggle
Обновление расписанияPATCH /schedules/:id
Удаление расписанияDELETE /schedules/:id
Обработчики событийПросмотрСписок обработчиков событийGET /event_listeners
Просмотр информации об обработчике событийGET /event_listeners/:id
Создание, изменение и удалениеСоздание обработчика событийPOST /event_listeners
Переключение обработчика событийPOST /event_listeners/toggle
Обновление обработчика событийPATCH /event_listeners/:id
Удаление слушателя событийDELETE /event_listeners/:id
ПользователиПросмотрСписок пользователейGET /users
Просмотр информации о пользователеGET /users/:id
Просмотр привилегий пользователяGET /users/:id/privileges
Просмотр ролей пользователяGET /users/:id/roles
Создание и изменениеСоздание пользователяPOST /users
Изменение статуса пользователяPOST /users/:id/toggle_status
Сброс пароля пользователяPOST /users/:id/reset_password
Обновление пользователяPATCH /users/:id
Обновление привилегий пользователяPATCH /users/:id/privileges
Обновление ролей пользователяPATCH /users/:id/roles
РолиПросмотрПросмотр ролейGET /roles
Просмотр информации о ролиGET /roles/:id
Просмотр привилегий ролиGET /roles/:id/privileges
Просмотр родительских ролейGET /roles/:id/parent_roles
Создание, изменение и удалениеСоздание ролиPOST /roles
Обновление ролиPATCH /roles/:id
Обновление привилегий ролиPATCH /roles/:id/privileges
Обновление родительских ролейPATCH /roles/:id/parent_roles
Удаление ролиDELETE /roles/:id

Описание всех используемых методов API приведено на странице API Onebridge

API

API OneBridge поддерживает HTTPS-протоколы. В API OneBridge используются GET-, POST-, PATCH- и DELETE-запросы.

Каждый запрос начинается с URL http://<host>, за ним следует название метода и параметры, при необходимости. Например, запрос для получения информации о запуске графа может быть записан так: http://127.0.0.1:3000/api/runs/154 или https://onebridge-dev.dev.allbridge.ru/api/runs/154. В таблицах с описанием методов будут указаны относительные пути URL-запросов.

Список API-методов системы OneBridge, доступных для вызова:

Resources

get info

ПараметрЗначение
ОписаниеПросмотр основной информации о сервере
МетодGET
URL запроса
/api/info
Параметры запросабез параметров
Структура ответа
name: string, 
ip_addrs: [string],
os: string,
uptime: integer,  
local_time: date-time,  
utc_time: date-time.
Пример ответа
{
  "name": "onebridge@sbar-dev-app01",
  "ip_addrs": [
    "ens192 10.131.1.101/24"
  ],
  "os": "Debian GNU/Linux 12 (bookworm)\n",
  "uptime": 339187,
  "local_time": "2025-02-25T10:12:42.143302793+03:00",
  "utc_time": "2025-02-25T07:12:42.143338945Z"
}

get performance

ПараметрЗначение
ОписаниеПросмотр данных о работе сервера для отображения графиков работы памяти, процессора и запущенных заданий
МетодGET
URL запроса
/api/performance
Параметры запросабез параметров
Структура ответа возвращает JSON файл со структурой, которая содержит объекты, описывающие состояние памяти, процессора и запущенных заданий:

ram: объект с информацией о памяти

datetime: date-time,  
total: string, 
used: string

cpu: объект с информацией о процессоре

datetime: date-time,
usage: string

job: объект с информацией о запущенных заданиях

datetime: date-time,
jobs: integer
Пример ответа

"ram": {
    "system_ram": 
    [
        {
        "datetime": "2023-06-13T06:37:36Z",
        "total": "16777785344",
        "used": "1356226560"
        },
    ...],
    "worker_ram": []  },
"cpu": {
    "system_cpu": 
    [
        {
        "datetime": "2023-06-13T06:37:36Z",
        "usage": "0.21265951"
        },
    ...],
    "worker_cpu": []  
    },
"jobs": {
    "jobs": 
    [
      {
      "datetime": "2025-03-06T15:07:37.895436576+03:00",
      "jobs": 0
      },
...]

get utilization

ПараметрЗначение
ОписаниеПросмотр данных о количестве используемой памяти сервера
МетодGET
URL запроса
/api/utilization
Параметры запросабез параметров
Структура ответа
name: string,
total: integer,
used: integer
Пример ответа
"name":"System RAM",
"total":16777785344,
"used":1351917568

Execution

get job params

ПараметрЗначение
ОписаниеПросмотр параметров задания
МетодGET
URL запроса
api/job_params?path=/project/directory/graphname.grf
Параметры запроса
path: string
Структура ответа
name: string
{
  value: string,
  required: boolean,
  encrypted: boolean
}
Пример ответа
{
    "count": {
        "value": "1",
        "required": false,
        "encrypted": false
    },
    "str": {
        "value": "Hello, world!",
        "required": false,
        "encrypted": false
    }
}

get run by id

ПараметрЗначение
ОписаниеПросмотр информации о запуске задания по id
МетодGET
URL запроса
/api/runs/id
Параметры запросабез параметров
Структура ответа
id: integer,  
started: date-time,  
finished: date-time, (необязательно)  
job_file: string,  
status: string, возможные значения: "Succeeded", "Failed", "InProgress"
params: {
    name: string {
        value: integer,
        required: boolean,
        encrypted: boolean
    }
},
project_id: string,
launch_type: string (варианты: manual, child_call, schedule, event_listener),
user: string.
children: [string], (необязательно)  
root: boolean
Пример ответа
{
  "id": "1039",
  "started": "2025-03-05T11:27:26.115895190+03:00",
  "finished": "2025-03-05T11:27:46.129338590+03:00",
  "job_file": "/ready-check/1232_encryptedParams.grf",
  "status": "Succeeded",
  "params": {
    "JOB_FILE": "1232_encryptedParams.grf",
    "SANDBOX_ROOT": "/opt/onebridge-dev/projects/ready-check",
    "SECONDS": {
      "value": "20",
      "required": "true",
      "encrypted": "true"
    }
  },
  "project_id": "ready-check",
  "launch_type": "manual",
  "user": "sofiko",
  "children": [],
  "root": true
}

get runs

ПараметрЗначение
ОписаниеПросмотр списка заданий
МетодGET
URL запроса
api/runs?offset=0&limit=25&includeRoot=true
Параметры запроса
from: date-time, начало интервала работы графа, необязательно  
to: date-time, конец интервала работы графа, необязательно  
job_file: string, имя файла, необязательно  
status: string, статус выполнения, необязательно  
offset: integer, начальный индекс в актуальном списке запущенных заданий, необязательно   
limit: integer, количество записей, которые нужно прислать, необязательно   
order: string, порядок сортировки ответов, возможные значения: "Asc", "Desc", по умолчанию order = "Desc"
Структура ответа
id: string,  
parent_id: string, (необязательно)  
started: date-time,  
job_file: string,  
status: string, возможные значения: "Succeeded", "Failed", "InProgress"
user: string
Пример ответа
[
  {
    "id": "1045",
    "parent_id": null,
    "started": "2025-03-07T12:15:33.679945596+03:00",
    "job_file": "/bug-checking/lookup_table_writer.grf",
    "status": "Succeeded",
    "user": "admin"
  },
  {
    "id": "1044",
    "parent_id": null,
    "started": "2025-03-05T12:17:53.216573428+03:00",
    "job_file": "/bug-checking/1148_data_transfer_row_count_1.grf",
    "status": "Failed",
    "user": "sofiko"
  },
  {
    "id": "1043",
    "parent_id": null,
    "started": "2025-03-05T11:34:00.002568904+03:00",
    "job_file": "/ready-check/1232_encryptedParams.grf",
    "status": "Failed",
    "user": "root"
  },
  {
    "id": "1042",
    "parent_id": null,
    "started": "2025-03-05T11:32:00.002515507+03:00",
    "job_file": "/ready-check/1048_NaN.grf",
    "status": "Failed",
    "user": "root"
  },
  {
    "id": "1041",
    "parent_id": null,
    "started": "2025-03-05T11:29:25.143493799+03:00",
    "job_file": "/ready-check/1232_encryptedParams.grf",
    "status": "Succeeded",
    "user": "sofiko"
  }
]

get runs in progress

ПараметрЗначение
ОписаниеПросмотр списка запущенных на данный момент заданий
МетодGET
URL запроса
api/runs/inProgress
Параметры запросаБез параметров
Структура ответа
id: string,   
started:  date-time,
finished: date-time,
job_file: string,  
status: string, возможные значения: "Succeeded", "Failed", "InProgress"
children: [string]
Пример ответа
[
  {
    "id": 1046,
    "started": "2025-03-07T13:54:44.674032212+03:00",
    "finished": null,
    "job_file": "/ready-check/1232_encryptedParams.grf",
    "status": "InProgress",
    "children": []
  },
  {
    "id": 1047,
    "started": "2025-03-07T13:54:47.740575439+03:00",
    "finished": null,
    "job_file": "/ready-check/1232_encryptedParams.grf",
    "status": "InProgress",
    "children": []
  }
]

post runs

ПараметрЗначение
ОписаниеЗапускает задание в работу и возвращает номер запущенного задания
МетодPOST
URL запроса
/api/runs
Параметры запросабез параметров
Тело запроса
job_file: string, имя задания   
params: {        
    name: string, имя параметра  {
        encrypted: boolean, шифрованность параметра
        required: boolean, обязательность параметра
        value: string - значение параметра  
    }
}
Пример запроса
{
    "job_file":"/bug-checking/1187_params.grf",
    "params":  {
        "count":  {
            "value":"2",
            "required":false,
            "encrypted":false
        },
        "str":  {
            "value":"1",
            "required":false,
            "encrypted":false
        }
    }
}
Структура ответа
id: string
Пример ответа
"id":"162"

get run position

ПараметрЗначение
ОписаниеПросмотр позиции запуска
МетодGET
URL запроса
/api/runs/position?id=14
Параметры запроса
id: string
Структура ответа
position: integer
Пример ответа
{
  "position": 577
}

get runs log

ПараметрЗначение
ОписаниеПросмотр логов запуска
МетодGET
URL запроса
/api/runs/id/log?last_bytes=1024
Параметры запроса
last_bytes: integer, ограничение длины логов, необязательно
Структура ответаlog: string
Пример ответа
2024-01-17T18:51:13.214084Z  INFO edge started id="DataGenerator0:e-2"
2024-01-17T18:51:13.214109Z  INFO edge started id="DataGenerator1:e-1"
2024-01-17T18:51:13.214113Z  INFO edge started id="HashJoin0:e-2"
2024-01-17T18:51:13.214116Z  INFO edge started id="HashJoin0:e-3"
2024-01-17T18:51:13.274860Z  INFO node succeeded id="FlatFileWriter2" duration=0 received=2500 sent=0
2024-01-17T18:51:13.274890Z  INFO node succeeded id="FlatFileWriter3" duration=0 received=0 sent=0
2024-01-17T18:51:13.274898Z  INFO node succeeded id="HashJoin0" duration=0 received=5500 sent=2500
2024-01-17T18:51:13.274902Z  INFO node succeeded id="DataGenerator1" duration=0 received=0 sent=3000
2024-01-17T18:51:13.274906Z  INFO node succeeded id="DataGenerator0" duration=0 received=0 sent=2500
2024-01-17T18:51:13.274917Z  INFO phase finished number=0 duration=0

get runs num

ПараметрЗначение
ОписаниеКоличество запусков заданий. Можно добавить фильтр по статусу, дате и имени файла
МетодGET
URL запроса
/api/runs/num?from=2023-12-31T21:00:00%2B00:00&to=2024-01-19T21:00:00%2B00:00&job_file=test-cases%2Fgraphs%2FflatFileReader05.grf&status=Failed&includeRoot=true
Параметры запроса
from: date-time, необязательный
to: date-time, необязательный
job_file: string, необязательный
status: string, необязательный, возможные значения: "Succeeded", "Failed", "InProgress"
includeRoot: boolean
Структура ответа
runs_num: integer, количество запусков заданий, подходящих под критерии установленных фильтров
Пример ответа
{
  "runs_num": 409
}

get job content

ПараметрЗначение
ОписаниеПросмотр содержимого файла задания, актуального на момент его запуска
МетодGET
URL запроса
/api/runs/id/job_content
Параметры запроса
id: string
Структура ответа
content: string, контент файла
Пример ответа

"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Graph>\n    <Global>\n        <Metadata id=\"meta\">\n            <Record>\n                <Field name=\"foo\" type=\"integer\" />\n                <Field name=\"bar\" type=\"number\" />\n            </Record>\n        </Metadata>\n    </Global>\n    <Phase number=\"0\">\n        <Node id=\"datagen\" guiX=\"50\" guiY=\"200\" guiName=\"datagen\" recordsNumber=\"100\" type=\"DATA_GENERATOR\">\n            <attr name=\"generate\">\n                <![CDATA[\n                const MAX_FOO = 10;\n                const MAX_BAR = 1;\n                \n                function generate() {\n                    $out[0].foo = Math.floor(Math.random() * MAX_FOO);\n                    $out[0].bar = Math.random() * MAX_FOO;\n\n                    $out[1].foo = Math.floor(Math.random() * MAX_FOO);\n                    $out[1].bar = Math.random() * MAX_FOO;\n\n                    return ALL;\n                }\n                ]]>\n            </attr>\n        </Node>\n        <Node id=\"trash1\" guiX=\"200\" guiY=\"100\" guiName=\"trash\"  type=\"TRASH\"/>\n        <Node id=\"copy\"   guiX=\"200\" guiY=\"300\" guiName=\"copy\"   type=\"SIMPLE_COPY\"/>\n        <Node id=\"trash2\" guiX=\"400\" guiY=\"400\" guiName=\"trash2\"  type=\"TRASH\"/>\n        <Node id=\"filter\" guiX=\"400\" guiY=\"300\" guiName=\"filter\" type=\"FILTER\">\n            <attr name=\"filterExpression\">\n                <![CDATA[ $in[0].foo < 3; ]]>\n            </attr>\n        </Node>\n        <Node id=\"sort\" guiX=\"550\" guiY=\"300\" guiName=\"sort\"  type=\"FAST_SORT\" sortKey=\"foo(a);bar(d)\" sortInMemory=\"false\" />\n        <Node id=\"trash3\"    guiX=\"700\" guiY=\"300\" guiName=\"trash\" type=\"TRASH\"/>\n\n        <Edge id=\"edge1\" fromNode=\"datagen:0\" toNode=\"trash1:0\" metadata=\"meta\" /> \n        <Edge id=\"edge2\" fromNode=\"datagen:1\" toNode=\"copy:0\"   metadata=\"meta\" />\n        <Edge id=\"edge3\" fromNode=\"copy:0\"    toNode=\"filter:0\" metadata=\"meta\" /> \n        <Edge id=\"edge4\" fromNode=\"copy:1\"    toNode=\"trash2:0\" metadata=\"meta\" />\n        <Edge id=\"edge5\" fromNode=\"filter:0\"  toNode=\"sort:0\"   metadata=\"meta\" />\n        <Edge id=\"edge6\" fromNode=\"sort:0\"    toNode=\"trash3:0\" metadata=\"meta\" />\n    </Phase>\n</Graph>"

get run stats

ПараметрЗначение
ОписаниеПросмотр статистики по запуску
МетодGET
URL запроса
/api/runs/id/stats
Параметры запросабез параметров
Структура ответа
id: integer {
    duration: integer,
    nodes: {
        node_name: string : {
            duration: integer,
            error: string,
            in_ports: [
                {
                    avg_rps: integer,
                    max_rps: integer,
                    records: integer,
                    rps: integer
                }
            ],
            out_ports: [
                {
                    avg_rps: integer,
                    max_rps: integer,
                    records: integer,
                    rps: integer
                }   
            ],
            status: string            
        }
    }
}
Пример ответа
{
  "0": {
    "duration": 0,
    "nodes": {
      "DatabaseReader0": {
        "duration": 0,
        "status": "Succeeded",
        "error": null,
        "in_ports": {},
        "out_ports": {
          "0": {
            "records": 100,
            "rps": 0.0,
            "avg_rps": 5033.325902466526,
            "max_rps": 5033.325902466526
          }
        }
      }
    }
  },
  "20": {
    "duration": 6,
    "nodes": {
      "DbJoin0": {
        "duration": 6,
        "status": "Succeeded",
        "error": null,
        "in_ports": {
          "0": {
            "records": 100,
            "rps": 0.0,
            "avg_rps": 16.346543267496433,
            "max_rps": 36.617655443638384
          }
        },
        "out_ports": {
          "0": {
            "records": 100,
            "rps": 0.0,
            "avg_rps": 16.346543267496433,
            "max_rps": 16.982217325860482
          },
          "1": {
            "records": 0,
            "rps": 0.0,
            "avg_rps": 0.0,
            "max_rps": 0.0
          }
        }
      },
      "FlatFileWriter0": {
        "duration": 5,
        "status": "Succeeded",
        "error": null,
        "in_ports": {
          "0": {
            "records": 100,
            "rps": 0.0,
            "avg_rps": 16.751940970341305,
            "max_rps": 16.982217325860482
          }
        },
        "out_ports": {}
      },
      "FlatFileWriter1": {
        "duration": 0,
        "status": "Succeeded",
        "error": null,
        "in_ports": {
          "0": {
            "records": 0,
            "rps": 0.0,
            "avg_rps": 0.0,
            "max_rps": 0.0
          }
        },
        "out_ports": {}
      }
    }
  }
}

abort run

ПараметрЗначение
ОписаниеПрерывает выполнение задания
МетодPOST
URL запроса
/api/runs/id/abort
Параметры запросабез параметров
Структура ответа
response: string
Пример ответа
Success

get runs inspect

ПараметрЗначение
ОписаниеВозвращает данные о записях, прошедших по указанному ребру.
МетодGET
URL запроса
/api/runs/run_id/inspect?edge=edge_id
Параметры запросаedge:string (id ребра)
Структура ответа
name: string,
type: string,
value: string
Пример ответа
[
    [
        {
            "name": "date",
            "type": "date",
            "value": "2023-12-21 00:00:00 UTC"
        },
        {
            "name": "last_name",
            "type": "string",
            "value": "Gorilov"
        },
        {
            "name": "number",
            "type": "string",
            "value": "17.921\r"
        }
    ],
    [
        {
            "name": "date",
            "type": "date",
            "value": "2013-12-08 00:00:00 UTC"
        },
        {
            "name": "last_name",
            "type": "string",
            "value": "Алексеев"
        },
        {
            "name": "number",
            "type": "string",
            "value": "2.023\r"
        }
    ],
    [
        {
            "name": "date",
            "type": "date",
            "value": "2022-09-23 00:00:00 UTC"
        },
        {
            "name": "last_name",
            "type": "string",
            "value": "Vasin"
        },
        {
            "name": "number",
            "type": "string",
            "value": "0.02\r"
        }
    ],
    [
        {
            "name": "date",
            "type": "date",
            "value": "2016-11-25 00:00:00 UTC"
        },
        {
            "name": "last_name",
            "type": "string",
            "value": "Васькин"
        },
        {
            "name": "number",
            "type": "string",
            "value": "-0.231"
        }
    ]
]

encrypt

ПараметрЗначение
ОписаниеШифрует значение параметра.
МетодPOST
URL запроса
/api/encrypt
Параметры запросаplaintext:string (значение параметра)
Структура ответа
ciphertext: string (зашифрованное значение параметра)
Пример ответа
{
  "ciphertext": "9380d423659fc5a5c855f210b647ffbbc6684ae80836bfe4db2a6efc3f"
}

Projects

get tree

ПараметрЗначение
ОписаниеПросмотр дерева проектов
МетодGET
URL запроса
/api/tree
Параметры запросабез параметров
Структура ответа
name: string,
path: string,
type: string,
children: [string]
Пример ответа
[
    {
        "name": "folder1",
        "path": "/folder1",
        "type": "project",
        "children": [
            {
                "name": "data-in",
                "path": "/folder1/data-in",
                "type": "directory",
                "children": [
                    {
                        "name": "dev.order.csv",
                        "path": "/folder1/data-in/testData/dev.order.csv",
                        "type": "file",
                        "children": []
                    }
                ],

                "name": "data-out",
                "path": "/folder1/data-out",
                "type": "directory",
                "children": [
                    {
                        "name": "testData",
                        "path": "/folder1/data-out/testData",
                        "type": "directory",
                        "children": []
                    }
                ],
                
                "name": "graph",
                "path": "/folder1/graph",
                "type": "directory",
                "children": [
                    {
                        "name": "graph.grf",
                        "path": "/folder1/graph/graph.grf",
                        "type": "file",
                        "children": []
                    }
                ]
            }
        ]
    }
]

get directory

ПараметрЗначение
ОписаниеПросмотр информации об указанной директории
МетодGET
URL запроса
/api/directory?path="PATH"
Параметры запроса
path: string
Структура ответа
name: string,
path: string
Пример ответа
"name":"data-in",
"path":"/JobsForTests/data-in"

get project

ПараметрЗначение
ОписаниеПросмотр информации о проекте
МетодGET
URL запроса
/api/project?path="PATH"
Параметры запроса
path: string
Структура ответа
name: string,
path: string
Пример ответа
{
  "name": "test-cases",
  "path": "/test-cases"
}

get file

ПараметрЗначение
ОписаниеПросмотр информации о выбранном файле
МетодGET
URL запроса
/api/file?path="PATH"
Параметры запроса
path: string, путь к файлу
content: bool (необязательно, по умолчанию равен false, +"content=true" вернёт содержимое выбранного файла)
Структура ответа
name: string,
path: string,
size: integer,
modified: date-time
Пример ответа
"name":"concat.grf",
"path":"/JobsForTests/graph/others/concat.grf",
"size":1278,
"modified":"2023-04-17T12:47:39.073986214Z"

post project

ПараметрЗначение
ОписаниеСоздать проект
МетодPOST
URL запроса
/api/project?path="PATH"
Параметры запроса
path: string, путь к создаваемому проекту
template: bool, флаг создания проекта по шаблону, необязательно
Структура ответа
name: string,
path: string
Пример ответа
"name":"test2",
"path":"/test2"

post project rename

ПараметрЗначение
ОписаниеПереименовать проект
МетодPOST
URL запроса
/api/project/rename?path="PATH"&to="PROJECT"
Параметры запроса
path: string, путь к проекту, который переименовываем
to: string, новое имя проекта
Структура ответа
name: string,
path: string
Пример ответа
"name":"test44",
"path":"/test44"

post directory

ПараметрЗначение
ОписаниеСоздать директорию
МетодPOST
URL запроса
/api/directory?path="PATH"
Параметры запроса
path: string, путь к директории, которую создаём
Структура ответа
name: string,
path: string
Пример ответа
"name":"infolder",
"path":"/test-project/folder1"

post directory rename

ПараметрЗначение
ОписаниеИзменить название директории
МетодPOST
URL запроса
/api/directory/rename?path="PATH"&to="DIRECTORY"
Параметры запроса
path: string, путь к директории, которую переименовываем
to: string новое имя директории
Структура ответа
name: string,
path: string
Пример ответа
"name":" folder10",
"path":"/test22/folder10"

post file

ПараметрЗначение
ОписаниеСоздать файл
МетодPOST
URL запроса
/api/file?path="PATH"
Параметры запроса
path: string, путь к новому файлу
Структура ответа
name: string,
path: string,
size: integer,
modified: date-time
Пример ответа
"name": "kudo.grf",
"path": "/test44/tururu/lalala/kuku/oshshshs/kudo.grf",
"size": 0,
"modified": "2023-06-15T08:10:21.261541736Z"

post file rename

ПараметрЗначение
ОписаниеПереименовать файл
МетодPOST
URL запроса
/api/file/rename?path="PATH"&to="FILE"
Параметры запроса
path: string, директория файла, который переименовывается
to: string, новое имя файла
Структура ответа
name: string,
path: string,
size: integer,
modified: date-time
Пример ответа
"name": "fileNEW",
"path": "/test44/tururu/lalala/kuku/bip/fileNEW",
"size": 0,
"modified": "2023-06-14T14:04:37.625674537Z"

patch file

ПараметрЗначение
ОписаниеЗаменить контент файла
МетодPATCH
URL запроса
/api/file?path="PATH"
Параметры запроса
path: string, путь к изменяемому файлу  
sent_file: string, текст изменённого файла
Структура ответа
name: string,
path: string,
size: integer,
modified: date-time
Пример ответа
{
    "name": "dg02_out.txt",
    "path": "/test-cases/data-out/dg02_out.txt",
    "size": 13,
    "modified": "2024-01-18T08:37:47.819450853Z"
}

delete directory

ПараметрЗначение
ОписаниеУдалить директорию
МетодDELETE
URL запроса
/api/directory?path="PATH"
Параметры запроса
path: string, путь к удаляемой папке
Структура ответаничего не возвращает

delete file

ПараметрЗначение
ОписаниеУдалить файл
МетодDELETE
URL запроса
/api/file?path="PATH"
Параметры запроса
path: string, путь к удаляемому файлу
Структура ответаничего не возвращает

delete project

ПараметрЗначение
ОписаниеУдалить проект
МетодDELETE
URL запроса
/api/project?path="PATH"
Параметры запроса
path: string, путь к удаляемому проекту
Структура ответаничего не возвращает

get download folder

ПараметрЗначение
ОписаниеСкачать папку
МетодGET
URL запроса
/api/download?path="PATH"
Параметры запроса
path: string, путь к скачиваемому проекту\папке
Структура ответаВозвращает содержимое выбранной папки в виде zip-архива.

Schedules

get schedules

ПараметрЗначение
ОписаниеПросмотреть список расписаний
МетодGET
URL запроса
/api/schedules?offset=0&limit=15&order_by=name&order=asc&contains=
Параметры запроса
offset: string, необязательно
limit: string, необязательно
order_by: string, необязательно
order: string, необязательно
contains: string, необязательно
Структура ответа
id: integer,
name: string,  
enabled: bool, 
job_file: string,  
trigger:    "Once": date-time или   
            "Interval": integer или   
            "Cron": string,  
last_run: date-time, (необязательно)  
next_run: date-time, (необязательно) 
run_status: string 
Пример ответа
[
  {
    "id": 4,
    "name": "1232",
    "enabled": true,
    "job_file": "/ready-check/1232_encryptedParams.grf",
    "once": "2025-02-13T12:44:00+03:00",
    "last_run": "2025-02-13T12:44:00+03:00",
    "next_run": null,
    "run_status": "Failed"
  },
  {
    "id": 3,
    "name": "6",
    "enabled": true,
    "job_file": "/reg2/graph/copy_1.grf",
    "interval": 60,
    "last_run": "2025-02-07T10:30:00+03:00",
    "next_run": null,
    "run_status": "Succeeded"
  },
  {
    "id": 2,
    "name": "11",
    "enabled": true,
    "job_file": "/bug-checking/825_params.grf",
    "once": "2025-02-05T13:12:00+03:00",
    "last_run": "2025-02-05T13:12:00+03:00",
    "next_run": null,
    "run_status": "Succeeded"
  },
  {
    "id": 1,
    "name": "123",
    "enabled": true,
    "job_file": "/test_nse/gen.grf",
    "interval": 30,
    "last_run": "2025-02-05T13:01:34.506441579+03:00",
    "next_run": null,
    "run_status": "Succeeded"
  }
]

get schedule by id

ПараметрЗначение
ОписаниеВыбор расписания по id
МетодGET
URL запроса
/api/schedules/schedule_id
Параметры запросабез параметров
Структура ответа
id: integer,
name: string,  
enabled: bool,  
trigger:    "Once": date-time или   
            "Interval": integer или   
            "Cron": string,  
active_from: date-time, (необязательно)  
active_to: date-time, (необязательно)  
job_file: string,  
params: {
    name: string {
        value: string,
        encrypted: boolean
    }
} 
last_run: date-time, (необязательно)  
next_run: date-time, (необязательно) 
created_by: string,
created_at: date-time,  (необязательно)
modified_by: string, (необязательно)
modified_at: date-time, 
run_info: {             (необязательно)
          id: integer, 
          started: datetime, 
          finished: datetime, (необязательно)
          status: string 
}
Пример ответа
{
  "id": 2,
  "name": "11",
  "enabled": true,
  "once": "2025-02-05T13:12:00+03:00",
  "active_from": null,
  "active_to": null,
  "job_file": "/bug-checking/825_params.grf",
  "params": [
    {
      "name": "JOB_FILE",
      "value": "825_params.grf",
      "encrypted": "true"
    },
    {
      "name": "SANDBOX_ROOT",
      "value": "/opt/onebridge-dev/projects/bug-checking",
      "encrypted": "true"
    },
    {
      "name": "prm1",
      "value": "11",
      "encrypted": "false"
    },
    {
      "name": "prm2",
      "value": "fsrg",
      "encrypted": "false"
    },
    {
      "name": "prm3",
      "value": "rw3747f374 rwtrty 24rwtrtyhbdjhcbsjfhajsbjhbjabjdhbcabdhcjsabhcacbasdhcbaichbsdhcbsdhcbsdchbsadhcbsjachbsjadcbh asdcbdbchchbwCBddcbdlcbDBVCdecIDBCADBALlbcl 24rwtrtyh bdjhcbsjfhajsbjhbjabjdhbcabdhcjsabhcacbasdhcbaichbsdh cbsdhcbsdchbsadhcbsjachbsj",
      "encrypted": "true"
    }
  ],
  "last_run": "2025-02-05T13:12:00+03:00",
  "next_run": null,
  "created_by": "sofiko",
  "created_at": "2025-02-05T13:11:15.737006504+03:00",
  "modified_by": "",
  "modified_at": null,
  "run_info": {
    "id": 571,
    "started": "2025-02-05T13:12:00.001963145+03:00",
    "finished": "2025-02-05T13:12:00.014304926+03:00",
    "status": "Succeeded"
  }
}

get schedules num

ПараметрЗначение
ОписаниеКоличество расписаний
МетодGET
URL запроса
/api/schedules/num?contains=
Параметры запроса
contains:string
Структура ответа
num:integer
Пример ответа
{
  9
}

get schedules position

ПараметрЗначение
ОписаниеПозиция расписания по id
МетодGET
URL запроса
/api/schedules/schedule_id/position
Параметры запросабез параметров
Структура ответа
position:integer
Пример ответа
{
  3
}

post schedules

ПараметрЗначение
ОписаниеСоздать расписание
МетодPOST
URL запроса
/api/schedules
Параметры запросабез параметров
Тело запроса
name: string,  
enabled: bool,  
trigger: {
    возможные значения:
    "Once": date-time или   
    "Interval": integer или   
    "Cron": string, 
}        
active_from: date-time, необязательно  
active_to: date-time, необязательно  
job_file: string,  
params: {  
    name: string {
        encrypted: boolean,
        required: boolean,
        value: string 
    }  
} 


Структура ответа
id: integer,
last_run: date-time, необязательно  
next_run: date-time, необязательно
Пример ответа
{
  "id":17,
  "last_run":null,
  "next_run":"2025-03-10T10:08:00+03:00"
}

post toggle schedules

ПараметрЗначение
ОписаниеИзменить состояние расписания (вкл/выкл)
МетодPOST
URL запроса
/api/schedules/schedule_id/toggle
Параметры запросабез параметров
Структура ответа
enabled: bool,
next_run: date-time, необязательно
Пример ответа
"enabled":true,
"next_run":null

delete schedules

ПараметрЗначение
ОписаниеУдалить расписание
МетодDELETE
URL запроса
/api/schedules/schedule_id
Параметры запросабез параметров
Структура ответаничего не возвращает

patch schedules

ПараметрЗначение
ОписаниеИзменить атрибуты расписания
МетодPATCH
URL запроса
/api/schedules/schedule_id
Параметры запросабез параметров
Тело запроса
name: string,   (не обязательно)
enabled: bool,  (не обязательно)
trigger:        (не обязательно)
         "Once": date-time или
         "Interval": integer или
         "Cron": string,
active_from: date-time, (не обязательно)
active_to: date-time,   (не обязательно)
job_file: string,       (не обязательно)
params:                 (не обязательно)
    {
        name: string,
        value: string
    }
Структура ответа
id: integer,
name: string,
enabled: bool,
trigger: "Once": date-time или
         "Interval": integer или 
         "Cron": string,
active_from: date-time, 
active_to: date-time, 
job_file: string,
params: {
    name: string,
    value: string,
    encrypted: string
},
last_run: date-time,
next_run: date-time
Пример ответа
{
  "id": 14,
  "name": "ewewer",
  "enabled": true,
  "once": "2025-03-13T00:00:00+03:00",
  "active_from": null,
  "active_to": null,
  "job_file": "/bug-checking/0_execGraph.grf",
  "params": [
    {
      "name": "JOB_FILE",
      "value": "0_execGraph.grf"
    },
    {
      "name": "SANDBOX_ROOT",
      "value": "/opt/onebridge-dev/projects/bug-checking"
    }
  ],
  "last_run": null,
  "next_run": "2025-03-13T00:00:00.000000006+03:00"
}

Event listeners

get event listeners

ПараметрЗначение
ОписаниеПросмотр списка обработчиков событий
МетодGET
URL запроса
/api/event_listeners
Параметры запроса
offset: integer, необязательно
limit: integer, необязательно
order_by: string, необязательно
order: string, необязательно
contains: string, необязательно
Структура ответа
id: integer,
name: string,
enabled: bool,
last_run: date-time, (необязательно) 
run_status: string,  (необязательно), возможные значения: Succeeded, Failed, InProgress, Aborted, Unknown
Пример ответа
[
  {
    "id": 1,
    "name": "111",
    "enabled": true,
    "last_run": null,
    "run_status": null
  },
  {
    "id": 2,
    "name": "6",
    "enabled": true,
    "last_run": "2025-02-26T10:01:33.903891189+03:00",
    "run_status": "Succeeded"
  },
  {
    "id": 3,
    "name": "Event listener 22",
    "enabled": true,
    "last_run": null,
    "run_status": null
  },
  {
    "id": 4,
    "name": "Event listener 3",
    "enabled": true,
    "last_run": null,
    "run_status": null
  }
]

get event listener by id

ПараметрЗначение
ОписаниеВыбор обработчика событий по id
МетодGET
URL запроса
/api/event_listeners/listener_id
Параметры запросабез параметров
Структура ответа
id: integer,
name: string,
enabled: bool,
action: {
    Command {
        program: string,
        args: string,
    },
или
    StartJob {
        job_file: string,
        params: {
            name: string {
                value: string,
                encrypted: boolean
            }
        },
    },
},
event: {
    Job{
        Finished { 
            job_file: string 
        }
    },
или
    File {
        filesystem: string (Local), 
        path: string, 
        check: string (Added/Removed), 
        interval: integer, 
    }
},
last_run: date-time
created_by: string,
created_at: datetime,
modified_by: string,
modified_at: datetime,
run_info: id: integer,
          started: datetime,
          finished: datetime, (необязательно) 
          status: string
Пример ответа
{
  "id": 12,
  "name": "уу",
  "enabled": false,
  "action": {
    "start_job": {
      "job_file": "/bug-checking/1187_params.grf",
      "params": {
        "JOB_FILE": {
          "value": "1187_params.grf",
          "encrypted": false
        },
        "SANDBOX_ROOT": {
          "value": "/opt/onebridge-dev/projects/bug-checking",
          "encrypted": false
        },
        "count": {
          "value": "15",
          "encrypted": false
        },
        "str": {
          "value": "15",
          "encrypted": false
        }
      }
    }
  },
  "event": {
    "job": {
      "finished": {
        "status": "any",
        "job_file": "/bug-checking/1043_sort.grf"
      }
    }
  },
  "last_run": "2025-04-21T11:38:30.447592892+03:00",
  "created_by": "admin",
  "created_at": "2025-04-21T11:38:17.280127831+03:00",
  "modified_by": "admin",
  "modified_at": "2025-04-22T11:47:45.648334392+03:00",
  "run_info": {
    "id": 2133,
    "started": "2025-04-21T11:38:30.445305275+03:00",
    "finished": "2025-04-21T11:38:30.450381966+03:00",
    "status": "Succeeded"
  }
}

get event listeners num

ПараметрЗначение
ОписаниеПолучить количество расписаний
МетодGET
URL запроса
/api/event_listeners/num?contains=
Параметры запроса
contains: string
Структура ответа
num: integer
Пример ответа
5

get event listeners position

ПараметрЗначение
ОписаниеПолучить позицию расписания по его id
МетодGET
URL запроса
/api/event_listeners/listener_id/position
Параметры запросабез параметров
Структура ответа
position: integer
Пример ответа
17

post event listeners

ПараметрЗначение
ОписаниеСоздает обработчик событий
МетодPOST
URL запроса
/api/event_listeners
Параметры запросабез параметров
Тело запроса
name: string,   имя слушателя событий  
enabled: bool,  переключатель  
event:          отслеживаемое событие  
{  
    Job{  
        Finished {   
            job_file: string,   
            params    {
                name: string,
                value: string
            },
        }  
    },  
    File {  
        filesystem: Local,   
        path: string,   
        check: string ("Added"/"Removed"),   
        interval: integer,   
    }  
},  
action:         действие, которое необходимо выполнить, когда event завершится  
{  
    Command {  
        program: string,  
        args: string  
    },  
    StartJob {  
        job_file: string,  
        params: {  
            name: string {
                encrpited: boolean,
                required: boolean,
                value: string 
            } 
        }  
    }  
}   
Структура ответа
id: integer - id нового расписания

toggle event listeners

ПараметрЗначение
ОписаниеИзменить состояние обработчика событий (вкл/выкл)
МетодPOST
URL запроса
/api/event_listeners/listener_id/toggle
Параметры запроса
name: string
Структура ответа
enabled: bool
Пример ответа
{
  "enabled": true
}

delete event listeners

ПараметрЗначение
ОписаниеУдалить обработчик событий
МетодDELETE
URL запроса
/api/event_listeners/listener_id
Параметры запросабез параметров
Структура ответаничего не возвращает

patch event listeners

ПараметрЗначение
ОписаниеИзменить значения атрибутов обработчика событий
МетодPATCH
URL запроса
/api/event_listeners/listener_id
Тело запроса Все поля опциональные. Но при смене типа события event с "job" на "file" и наоборот, а так же при смене действия action с "Command" на "StartJob" и наоборот - нужно заполнить все сопутствующие атрибуты. Например, если обработчик был настроен на event "job", и нужно заменить его на event "file", то нужно будет задать значение и для атрибутов filesystem, check, path, interval.
name: string,
enabled: bool,  (не обязательно)
event:          (не обязательно)
        "job": Finished { 
            job_file: string 
        }
        "file": { 
            filesystem: "Local",
            path: string,
            check: "Added" или "Removed",
            interval: int,
        }
action:         (не обязательно)
        Command {
            program: string,
            args: string
        },
        StartJob {
            job_file: string,
            params: [
                name: String,
                value: String,
            ]
        } 
Структура ответа
name: string,   (имя остаётся прежним при использовании API patch event_listeners, меняется с помощью API create event_listeners_rename)
enabled: bool,  (новое состоние)
event:  Job     (новое задание или файл)
        {       
            Finished { 
                job_file: string 
            }
        }
        или
        File { 
            filesystem: Local,
            path: string,
            check: {
                Added,
                или
                Removed
            },
            interval: int,
        },
action: Command (новая команда или задание)
        {   
            program: string,
            args: string,
        }
        или
        StartJob {
            job_file: string,
            params: { 
                name: string,
                value: string,
            }
        }
Пример ответа
{
    "name": "listener_name",
    "enabled": false,
    "event": {
        "job": {
            "finished": {
                "job_file": "/JobsForTests/graph/others/concat.grf"
            }
        }
    },
    "action": {
        "start_job": {
            "job_file": "/JobsForTests/graph/others/filter.grf",
            "params": []
        }
    }
}

Auth

login

ПараметрЗначение
ОписаниеАвторизация пользователя в системе
МетодPOST
URL запроса
/auth/login
Параметры запросабез параметров
Тело запроса
username: string,  
password: string
Структура ответа
access_token: string,   
refresh_token: string, необязательно
Пример ответа
{
  "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6InRlc3QwMyIsInBhc3N3b3JkX2NoYW5nZV9yZXF1aXJlZCI6dHJ1ZSwicmVsb2dfcmVxdWlyZWQiOmZhbHNlLCJwcml2aWxlZ2VzIjpbXSwiZXhwIjoxNzA1NTA2MjM5fQ.Ec1gQ9fR6MN5uNDejJbHk4vnKyySrnv2ZOs3nuoYNvQ",
  "refresh_token": ""
}

logout

ПараметрЗначение
ОписаниеЗавершение сеанса работы в системе
МетодPOST
URL запроса
/auth/logout
Параметры запросабез параметров
Структура ответаничего не возвращает

refresh

ПараметрЗначение
ОписаниеОбновление токена
МетодPOST
URL запроса
/auth/refresh
Параметры запросабез параметров
Структура ответа
access_token: string,    
refresh_token: string
Пример ответа
{
  "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6InRlc3Q0IiwicGFzc3dvcmRfY2hhbmdlX3JlcXVpcmVkIjpmYWxzZSwicmVsb2dfcmVxdWlyZWQiOmZhbHNlLCJwcml2aWxlZ2VzIjpbXSwiZXhwIjoxNzA1NTYzNzk5fQ.YdxxXEr-1Ur8BB5nI27OZh3Ueo7BwFwJkx2vg8t44wA",
  "refresh_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6InRlc3Q0IiwicGFzc3dvcmRfY2hhbmdlX3JlcXVpcmVkIjpmYWxzZSwicmVsb2dfcmVxdWlyZWQiOmZhbHNlLCJwcml2aWxlZ2VzIjpbXSwiZXhwIjoxNzA1NTYzNzk5fQ.MBJeIlWnI_BH3MT2TjfhfmoTFhTQGylhpMYu32G6tOw"
}

change password

ПараметрЗначение
ОписаниеСмена пароля
МетодPOST
URL запроса
/auth/change_password
Тело запроса
old_pass: string,
new_pass: string
Структура ответаничего не возвращает

Users

post user

ПараметрЗначение
ОписаниеСоздание пользователя
МетодPOST
URL запроса
api/users
Параметры запросабез параметров
Тело запроса
username: string,     
first_name: string,     
last_name: string, необязательно    
email: string,  
Структура ответа
password: string 
Пример ответа
sNCYtII5bGcFRLJ9

post toggle user status

ПараметрЗначение
ОписаниеИзменение статуса пользователя
МетодPOST
URL запроса
api/users/[user_id]/toggle_status
Параметры запросабез параметров
Структура ответа
status: string, возможные значения: "Active", "Block"
Пример ответа
"Blocked"

post reset user password

ПараметрЗначение
ОписаниеСброс пароля пользователя
МетодPOST
URL запроса
api/users/[user_id]/reset_password
Параметры запросабез параметров
Структура ответа
password: string
Пример ответа
"B4YjaIGX8tTod6ZU"

patch user

ПараметрЗначение
ОписаниеРедактирование данных пользователя. Поменять можно полное имя (fullname) и email
МетодPATCH
URL запроса
api/users/[user_id]
Параметры запросабез параметров
Тело запроса
name: string,    
email: string
Структура ответаничего не возвращает

get user by id

ПараметрЗначение
ОписаниеПросмотр информации о пользователе
МетодGET
URL запроса
api/users/[user_id]?type=full
Параметры запроса
type: string, возможные значения: "full", "basic"
Структура ответа
username: string, - логин пользователя,   
password: string, - пароль, всегда "null",  
first_name: string, - имя пользователя,     
last_name: string,  - фамилия пользователя, необязательно  
auth_method: string, - метод аутентификации в системе, возможные значения: "Internal", "Ldap",   
email: string, - адрес электронной почты пользователя,   
user_status: string, - статус пользователя, возможные значения: "Active", "Blocked",     
password_required: bool, - необходимость ввода пароля,   
last_login_status: string, - статус последнего входа, возможные значения: "NotSet", "Success", "Failure",   
login_attempts: integer, - количество попыток входа,   
last_login_date: date-time,  - дата последней попытки входа, необязательно
Пример ответа
auth_method: "Internal"
email: "sammi@ya.ru"
first_name: "sam"
last_login_date: "2024-01-15T09:37:37.246933528Z"
last_login_status: "Success"
last_name: "smit"
login_attempts: 0
password: null
password_required: false
user_status: "Active"
username: "samael"

get users

ПараметрЗначение
ОписаниеПросмотр списка пользователей
МетодGET
URL запроса
api/users?offset=0&limit=15&order_by=id&order=desc&contains=&type=full
Параметры запроса
offset: integer,
limit: integer,
order_by: string,
order: string,
contains: string,
type: string,
Структура ответа
id: integer,
username: string, - логин пользователя,   
name: string, - имя пользователя,     
user_status: string, - статус последнего входа, возможные значения: "NotSet", "Success", "Failure"
last_login_date: datetime
Пример ответа
[
  {
    "id": 15,
    "username": "user144",
    "name": "user144",
    "user_status": "active",
    "last_login_date": null
  },
  {
    "id": 9,
    "username": "user9",
    "name": "user9",
    "user_status": "active",
    "last_login_date": null
  },
  {
    "id": 8,
    "username": "user8",
    "name": "user8",
    "user_status": "active",
    "last_login_date": null
  },
  {
    "id": 7,
    "username": "sbardeveloper",
    "name": "main developer))",
    "user_status": "active",
    "last_login_date": "2025-03-10T11:46:38.979308285+03:00"
  },
  {
    "id": 6,
    "username": "skhoperskaya",
    "name": "",
    "user_status": "active",
    "last_login_date": "2025-02-21T12:19:38.592916273+03:00"
  },
  {
    "id": 5,
    "username": "sofiko",
    "name": "",
    "user_status": "active",
    "last_login_date": "2025-03-10T14:00:37.570142141+03:00"
  },
  {
    "id": 4,
    "username": "nsense",
    "name": "nsense nsense",
    "user_status": "active",
    "last_login_date": "2025-02-21T11:30:21.271110750+03:00"
  }
]

Roles

get roles

ПараметрЗначение
ОписаниеПросмотр списка ролей
МетодGET
URL запроса
/api/roles
Параметры запроса
offset: integer,
limit: integer,
order_by: string,
order: string, (не обязательный)
contains: string, (не обязательный)
Структура ответа
role_id: integer,   
name: string, необязательно   
description: string, необязательно
is_editable: boolean
Пример ответа
[
  {
    "role_id": 1,
    "name": "admin",
    "description": "Роль администратора",
    "is_editable": false
  },
  {
    "role_id": 2,
    "name": "test-role1",
    "description": "something",
    "is_editable": true
  },
  {
    "role_id": 3,
    "name": "test-role2",
    "description": "описание тестовой роли",
    "is_editable": true
  },
  {
    "role_id": 4,
    "name": "testrole3",
    "description": "описание новой тестовой роли",
    "is_editable": true
  }
]

get role

ПараметрЗначение
ОписаниеПросмотр конкретной роли по её id
МетодGET
URL запроса
/api/roles/[role_id]?type=full
Параметры запроса
type: string
Структура ответа
role_id: integer,   
name: string, необязательно   
description: string, необязательно
is_editable: boolean
Пример ответа
{
  "role_id": 3,
  "name": "administrator",
  "description": "admin for ldap",
  "is_editable": true
}

post role

ПараметрЗначение
ОписаниеСоздание роли
МетодPOST
URL запроса
/api/roles
Параметры запросабез параметров
Тело запроса
name: string, - новое имя роли, необязательно  
description: string, - новое описание роли, необязательно
Пример ответаничего не возвращает

patch role

ПараметрЗначение
ОписаниеРедактирование роли
МетодPATCH
URL запроса
/api/roles/[role_id]
Параметры запросабез параметров
Тело запроса
name: string,
description: string    
Пример ответаничего не возвращает

delete role

ПараметрЗначение
ОписаниеУдаление роли
МетодDELETE
URL запроса
/api/roles/[role_id]
Параметры запросабез параметров
Структура ответаничего не возвращает

get privileges

ПараметрЗначение
ОписаниеПросмотр списка всех существующих привилегий
МетодGET
URL запроса
api/privileges
Параметры запросабез параметров
Структура ответа
privilege_id: integer,
name_ru: string,
name_en: string,
api_method_name: string,
Пример ответа
[
  {
    "privilege_id": 1,
    "name_ru": "Создание пользователя",
    "name_en": "Create User",
    "api_method_name": "POST /users",
    // "group_name": "Users"
  },
  {
    "privilege_id": 2,
    "name_ru": "Изменение статуса пользователя",
    "name_en": "Toggle User Status",
    "api_method_name": "POST /users/[user_id]/toggle_status",
    // "group_name": "Users"
  },
  {
    "privilege_id": 7,
    "name_ru": "Просмотр ролей",
    "name_en": "View Roles",
    "api_method_name": "GET /roles",
    // "group_name": "Roles"
  },
  {
    "privilege_id": 19,
    "name_ru": "Просмотр параметров задания",
    "name_en": "View Job Parameters",
    "api_method_name": "GET /job_params",
    // "group_name": "Runs"
  },
   {
    "privilege_id": 21,
    "name_ru": "Просмотр статистики запуска",
    "name_en": "View Run Stats",
    "api_method_name": "GET /runs/:id/stats",
    // "group_name": "Runs"
  },
   {
    "privilege_id": 51,
    "name_ru": "Создание расписания",
    "name_en": "Create Schedule",
    "api_method_name": "POST /schedules",
    // "group_name": "Schedules"
  }
]

get role privileges

ПараметрЗначение
ОписаниеПросмотр привилегий роли
МетодGET
URL запроса
api/roles/[role_id]/privileges
Параметры запросабез параметров
Структура ответа
id: privileges
Пример ответа
[
  1,
  2,
  3,
  4,
  5,
  6,
  7,
  8,
  9,
  10,
  11,
  12,
  13,
  14,
  15
]

patch role privileges

ПараметрЗначение
ОписаниеОбновление привилегий роли
МетодPATCH
URL запроса
api/roles/[role_id]/privileges
Параметры запросабез параметров
Тело запроса
{
  "privileges": [4,5,6]
}
Структура ответаничего не возвращает

get role subroles

ПараметрЗначение
ОписаниеПросмотр субролей роли по её id
МетодGET
URL запроса
api/roles/[role_id]/subroles
Параметры запросабез параметров
Структура ответа
role_id: integer
Пример ответа
[4,5]

patch role subroles

ПараметрЗначение
ОписаниеИзменение субролей роли
МетодPATCH
URL запроса
api/roles/[role_id]/subroles
Тело запроса
{
  "sub_roles": [4,5] //список role_id ролей, которые должны быть назначены субролями для роли, указанной в URL-запросе
}
Структура ответаничего не возвращает

get user roles

ПараметрЗначение
ОписаниеПросмотр ролей конкретного пользователя
МетодGET
URL запроса
/api/users/[user_id]/roles
Параметры запросабез параметров
Структура ответа
role_id: integer
Пример ответа
[
  [6,4]
]

patch user roles

ПараметрЗначение
ОписаниеОбновление ролей пользователя
МетодPATCH
URL запроса
/api/roles/[user_id]/roles
Тело запроса
{
  "roles": [3,5] //список role_id, присваеваемых пользователю
}

Структура ответаничего не возвращает

get user privileges

ПараметрЗначение
ОписаниеПросмотр привилегий пользователя
МетодGET
URL запроса
/api/users/[user_id]/privileges
Параметры запросабез параметров
Структура ответа
privilege_id: integer
Пример ответа
[
  28,
  29,
  30,
  31,
  32,
  33,
  19,
  20,
  21,
  22,
  23,
  24,
  25,
  26,
  27,
  62,
  34,
  35,
  36,
  37,
  38,
  39,
  40,
  41,
  42,
  43,
  44,
  45,
  46,
  47,
  48,
  49,
  50,
  7,
  8,
  9,
  10,
  11,
  12,
  13,
  14,
  15,
  16,
  17,
  18,
  57,
  1,
  2,
  3,
  4,
  5,
  6
]

patch user privileges

ПараметрЗначение
ОписаниеОбновление привилегий пользователя
МетодPATCH
URL запроса
/api/users/[user_id]/privileges
Тело запроса
"privileges": [список id присваемых пользователю привилегий]
Структура ответаничего не возвращает

get version

ПараметрЗначение
ОписаниеВозвращает актуальную версию сборки приложения
МетодGET
URL запроса
/api/version
Параметры запросабез параметров
Структура ответа
version: string,
commit: string
Пример ответа
{"version":"1.x.x","commit":"94889c7a70f7444a429b07c2e2b5f9bcfb2028d0"}

Выпущенные версии OneBridge

Номер версииДата выпускаОписание
1.21.02025-03-21Доработана интеграция с LDAP, добавлен учет входов для LDAP пользователей. Проведена подготовка для внедрения нового языка. Скорректирована логика API для расписаний, обработчиков событий, пользователей и ролей. Исправлена работа поиска для пользователей, ролей, расписаний, обработчиков событий.

Переработана ролевая модель. Исправлена ошибка выхода из системы для пользователя без привилегий.

Исправлены дефолтные значения для некоторых атрибутов шагов. Изменена схема копирования ребер и шагов.

1.20.02025-02-03Добавлен шаг HTTP_CONNECTOR. Проведен рефакторинг worker. Добавлена аутентификация LDAP пользователей. Добавлены проверки в шаги MergeJoin, DBReader и ExecuteGraph.

Доработаны апи для работы с запуском графов и информацией о хосте.

В дизайнере исправлено наложение вкладок с файлами на панель компонентов, поправлено отображение статистики на ребрах графа, исправлен диалог удаления метадаты и вывод версии сборки.

1.19.02024-12-24Добавлен шаг CONCATENATE. Добавлены возможности: копировать и линковать хэш-таблицы и словари, перезапускать задания со старыми параметрами, возможность выбрать какое содержимое графа использовать - из истории или актуальное из проекта, принудительно запустить граф с карточки расписания и обработчика событий, запустить обработчики событий в зависимости от статуса выполненного графа. Улучшена защита при передаче зашифрованных параметров. Добавлен роутинг на странице проектов. В дизайнер добавлена возможность отключать шаги (дизейблинг) и копировать файлы.

Исправлены замечания по работе ODBC, добавлен шаблон подключения. Исправлен алгоритм расчёта статистики, работа расписаний и лисенеров. Скорректирована работа с дефолтными значениями для словарей и доработан вывод статистики на ребра графа.

1.18.02024-11-12Добавлены шаги - AGGREGATE, DEDUP, INPUT_TABLE, LOOKUP_TABLE_READER, LOOKUP_TABLE_WRITER. Добавлен роутинг на все страницы. Отказались от SSE в web и в designer. Хранение и вывод всех данных теперь в локальном времени. Добавлен параметр enabled для шагов. Теперь можно отключать и включать шаги для упрощения тестирования графов. Реализованы лукап таблицы. Добавлена возможность шифровать параметры. В расписаниях и событиях добавлен выбор проекта и графа отдельно.

Исправлена некорректная работа обработчиков событий. Соединение PostgresODBC в шаге DBExecute теперь закрывается. Больше не двоятся кавычки при попытке записать их в базу Postgres. NaN в значении поля с типом float корректно обрабатывается. Убрана проверка дефолтных значений dictionary. Устранена паника в коре при запуске невалидного графа через execute graph.

Улучшен обработчик событий. Реализован новый подход подключениий к серверам. Произведена корректировка типов и дефолтных значений атрибутов. Исправлены некоторые собщения об ошибках. Скорректирована проверка на целостность при сохранении файла.

1.17.02024-09-03Добавлен параллельный запуск графов через шаг ExecuteGraph. в DBReader исправлено чрезмерное потребление памяти. Соединение odbc теперь закрывается самостоятельно. Исправлены баги в работе MergeJoin, HashJoin, DbExecute, DataIntersection.

Добавлено отображение дерева ранов на страницу Ресурсы в вебе. Исправлены сохранение и передача информации о создании и редактировании расписаний и слушателей. Для расписаний и слушателей событий теперь отображается статус последнего запущенного задания.
В дизайнере появилась возможность удалять с рабочей области сразу все выделенные компоненты. Добавлено коипрование коннекшенов и параметров. Дерево ранов отображается на вкладке Log. Исправлена проверка самоподписанных сертификатов. Изменена величина ячеек сетки и управление прилипанием компонентов к сетке. Нативное подключение к firebird удалено, оставили возможность подключаться к firebird только через ODBC.

1.16.02024-08-05Добавлена возможность использовать printdebug в трансформациях и сохранять информацию по выполнению графа в преднастроенные dictionary. В историю выполнения добавлено дерево графов и исправлен вывод статистики на ребра графа. Поправлена работа джойнов. В дизайнере добавлено копирование метаданных, сетка для автовыравнивания шагов на рабочей области. Устранён баг с дублированием айдишников при добавлении новых шагов, при закрытии дизайнера проверяется наличие файлов с несохранёнными изменениями и выводится диалог. Исправлена работа ctrl+z.
1.15.02024-07-11Добавлены шаги EXECUTE_SCRIPT, LIST_FILES. Исправлены ошибки в поведении DATA_INTERSECTION, DBEXECUTE, DBJOIN, HASH_JOIN, EXECUTE_GRAPH. Добавлена возможность менять порядок метаданных в редакторе, сортировать все элементы панели Outline, копировать полный путь любого файла. Исправлено отображение ролей. Улучшен механизм присвоения меты ребрам - теперь можно перетаскивать метаданные с Outline прямо на ребро. Отрефакторен механизм управления запусками шагов.
1.14.02024-06-17Исправлена работа dataInspector и DATA_INTERSECTION, отображение графиков в Ресурсах. Изменено поведение EXECUTE_GRAPH и POSTGRESQL_DATA_WRITER.
1.13.02024-06-07Добавлены новые шаги: DATA_INTERSECTION, DBJOIN. Реализовано апи для dataInspector. Обновлено окно для генерации крон выражения при создании расписания. В дизайнере исправлена работа с горячими клавишами и типы некоторых полей, а также цвет теста на шагах и валидация графа перед запуском. Исправлены баги в отображении статистики и настройка расписаний при редеплое. Обновлена логика работы ребер.
1.12.02024-05-20Реализована выгрузка проектов и папок в виде архива, импорт настроек соединений и метаданных из файлов, добавлена поддержка firebird. На страницу ресурсов добавлен новый график запущенных заданий. Устранены ошибки в работе шагов DB_EXECUTE, EXECUTE_GRAPH. Внесены правки в Дизайнер в части отображения соединений с базами данных, добавлена возможность перетаскивать метаданные на ребро способом 'drag-and-drop', исправлено отображение редакторов объектов.
1.11.02024-04-23Реализованы шаги: DB_EXECUTE, EXECUTE_GRAPH, SUCCESS, FAIL, RAW_READER, RAW_WRITER. Устранены ошибки в работе шагов ROLLUP, CROSS_JOIN, FLAT_FILE_READER, SPREADSHEET_READER. Внесены правки в Дизайнер в части отображения атрибутов и шагов, добавлены заметки.
1.10.02024-02-29Улучшены сообщения об ошибках. Частично настроено использование sse для обновления данных. В Дизайнер добавлена возможность подстановки параметров во все атрибуты.
1.9.02024-01-25Добавлены новые шаги, исправлены ошибки. Доработан Дизайнер.
1.8.02023-12-28Проведён рефакторинг имеющихся API и Дизайнера.
1.7.02023-12-08Проведён рефакторинг имеющихся шагов.
1.6.02023-12-01Добавлен сбор и вывод статистики в Инспектор заданий, добавлены шаги. В Дизайнере обновлена логика заполнения атрибутов шагов, исправлены редакторы метаданных и шагов.
1.5.02023-10-01Добавлена базовая аутентификация, добавлены шаги для обработки данных, добавлена генерация и редактирование графов в Дизайнер.
1.4.02023-09-01Проведен рефакторинг созданных шагов, разработан Дизайнер.
1.3.02023-08-01Добавлены уведомления о событиях модуля управления и реализованы новые шаги.
1.2.02023-07-01Добавлены обработчики событий и реализованы новые шаги.
1.1.02023-06-01Добавлена функция создания расписаний запусков графов и реализованы новые шаги.
1.0.02023-05-01В модуле управления реализованы основные инструменты для управления заданиями по обработке данных и наблюдения за производительностью сервера.

Пример 1. Работа с простыми файлами, фильтрами, сортировкой

Описание задачи

Создать файл с заданием для обработки данных следующим образом:

  1. Прочитать данные из нескольких файлов.
  2. Объединить считанные потоки данных.
  3. Скопировать получившийся поток данных в несколько потоков.
  4. Вывести один из потоков в файл.
  5. Записи из второго потока отсортировать.
  6. Затем отфильтровать.
  7. Полученные данные записать в файл.

На рисунке ниже представлено графическое представление такого графа:

Отображение графа example_01.grf в инспекторе заданий

Заполнение файла задания

В начале создания файла нужно объявить, что его содержимое является заданием-графом, для этого открываем тег <Graph>.

Далее нужно открыть тег <Global>, в котором будут описаны метаданные и параметры графа.

Далее открываем элемент <Record>, атрибутами которого можно назначить fieldDelimiter – для объявления разделителя полей записи, и recordDelimiter – для указания символа, разделяющего записи.

Дочерним элементу <Record> является пустой элемент <Field>, у которого нет закрывающего тега. Его используем, чтобы указать имя (name) и тип данных (type) для полей записей.

Теперь поочередно закрываем теги </Record>, </Metadata> и </Global>.

Следующий открывающий тег - <Phase> с атрибутом number, указывающим номер фазы для определения очередности выполнения шагов. В этом примере фаза всего одна, ее номер можно не указывать.

Далее открываем три пустых элемента <Node>, атрибуты которых, описывают имя шага (id), входные и выходные файлы для шагов чтения и записи (file), типы шагов (type) и координаты для отрисовки шагов в инспекторе задач.

У элемента <Node> может быть дочерний элемент <Attr>, которому нужно задать имя name, а внутри записать логическое выражение для фильтрации или метод преобразования данных.

Еще нужно указать пустые теги <Edge> для описания ребер графа. В атрибутах этого элемента можно пояснить, какими ребрами какие шаги связать в этом графе и указать ссылку на метаданные, указанные в начале файла в теге <Metadata>.

В конце закрываем элементы </Phase> и </Graph>.

Получился файл задания:

<Graph>
    <Global>
        <Metadata id="ObjectWithPos">
            <Record fieldDelimiter="|" recordDelimiter="\n">
                <Field name="a" type="string"/>
                <Field name="b" type="integer"/>
                <Field name="c" type="float"/>
            </Record>
        </Metadata>
    </Global>
    
    <Phase number="0">
        <Node id="reader0" guiX="50"   guiY="100" guiName="FlatFileReader0" fileURL="data-in/others/example_01_in1.txt"   type="FLAT_FILE_READER"/>
        <Node id="reader1" guiX="50"   guiY="300" guiName="FlatFileReader1" fileURL="data-in/others/example_01_in2.txt"   type="FLAT_FILE_READER"/>
        <Node id="writer0" guiX="600"  guiY="100" guiName="FlatFileWriter0" fileURL="data-out/others/example_01_out1.txt" type="FLAT_FILE_WRITER"/>
        <Node id="writer1" guiX="600"  guiY="200" guiName="FlatFileWriter1" fileURL="data-out/others/example_01_out2.txt" type="FLAT_FILE_WRITER"/>
        <Node id="concat"  guiX="250"  guiY="200" guiName="Concat" type="CONCAT"/>
        <Node id="copy"    guiX="450"  guiY="200" guiName="Copy" type="SIMPLE_COPY"/>
        <Node id="sort"    guiX="650"  guiY="300" guiName="FileSortNode" sortKey="c(d)" type="EXT_SORT"/><!--"d" - descending-->
        
        <Node id="filter"  guiX="850" guiY="300" guiName="FilterNode" type="FILTER">
            <Attr name="filterExpression">
                <![CDATA[
                    $in[0].b > 0
                ]]>
            </Attr>
        </Node>
    
        <Edge id="edge0" fromNode="reader0:0" toNode="concat:0"/>
        <Edge id="edge1" fromNode="reader1:0" toNode="concat:1"/>
        <Edge id="edge2" fromNode="concat:0"  toNode="copy:0"/>
        <Edge id="edge6" fromNode="copy:0"    toNode="writer1:0" metadata="ObjectWithPos"/>
        <Edge id="edge5" fromNode="copy:1"    toNode="sort:0"/>
        <Edge id="edge3" fromNode="sort:0"    toNode="filter:0"/>
        <Edge id="edge4" fromNode="filter:0"  toNode="writer0:0" metadata="ObjectWithPos"/>
    </Phase>
</Graph>

Результат

На вход были поданы два файла:

файл 1:

werwr|234|25.45
krlgkrgw|63|-65.8
srgehdhdfxyjset___g_jgsn|72465|92745972
fbsb!efb|-42536356|0
glsdgh|453453|4524.545

файл 2:

Лёша на горе рога нашёл|-123|-123
Около Мити молоко|234|454.4
Тина барабанит|12|12.12

На выходе получены файлы:

файл 1 (содержит результат работы задания целиком):

glsdgh|453453|4524.545
werwr|234|25.45
Тина барабанит|12|12.12
fbsb!efb|-42536356|0.0
krlgkrgw|63|-65.8

файл 2 (содержит результат конкатенации двух потоков данных на втором шаге задания):

werwr|234|25.45
krlgkrgw|63|-65.8
srgehdhdfxyjset___g_jgsn|72465|92745970.0
fbsb!efb|-42536356|0.0
glsdgh|453453|4524.545
Лёша на горе рога нашёл|-123|-123.0
Около Мити молоко|234|454.4
Тина барабанит|12|12.12

Атрибуты используемых шагов

Атрибуты FlatFileReader:

АтрибутОбязательныйОписаниеВозможные значения
idдаНазвание шага для указания в атрибутах ребра fromNode и toNode. Может быть произвольным.id="reader"
guiXнетКоордината верхнего левого угла шага для отрисовки графа в инспекторе заданий.guiX="50"
guiYнетКоордината верхнего левого угла шага для отрисовки графа в инспекторе заданий.guiY="100"
guiNameнетИмя шага, указываемое на графе. Равно type шага. Нельзя изменять.guiName="FlatFileReader"
fileнетПуть к источнику данных для чтенияfile="data-in/others/example_01_in1.txt"
typeдаТип шага. Определяет функциональность данного шага.type="FlatFileReader"

Атрибуты Concat:

АтрибутОбязательныйОписаниеВозможные значения
idдаНазвание шага для указания в атрибутах ребра fromNode и toNode. Может быть произвольным.id="concat"
guiXнетКоордината верхнего левого угла шага для отрисовки графа в инспекторе заданий.guiX="50"
guiYнетКоордината верхнего левого угла шага для отрисовки графа в инспекторе заданий.guiY="100"
guiNameнетИмя шага, указываемое на графе. Равно type шага. Нельзя изменять.guiName="Concat"
typeдаТип шага. Определяет функциональность данного шага.type="Concat"

Атрибуты Copy:

АтрибутОбязательныйОписаниеВозможные значения
idдаНазвание шага для указания в атрибутах ребра fromNode и toNode. Может быть произвольным.id="copy"
guiXнетКоордината верхнего левого угла шага для отрисовки графа в инспекторе заданий.guiX="50"
guiYнетКоордината верхнего левого угла шага для отрисовки графа в инспекторе заданий.guiY="100"
guiNameнетИмя шага, указываемое на графе. Равно type шага. Нельзя изменять.guiName="Copy"
typeдаТип шага. Определяет функциональность данного шага.type="Copy"

Атрибуты FileSortNode:

АтрибутОбязательныйОписаниеВозможные значения
idдаНазвание шага для указания в атрибутах ребра fromNode и toNode. Может быть произвольным.id="sort"
guiXнетКоордината верхнего левого угла шага для отрисовки графа в инспекторе заданий.guiX="50"
guiYнетКоордината верхнего левого угла шага для отрисовки графа в инспекторе заданий.guiY="100"
guiNameнетИмя шага, указываемое на графе. Равно type шага. Нельзя изменять.guiName="FileSortNode"
sortKeyда

Имя поля для ключа и порядок сортировки.

«d» - «descending» - по убыванию

«a» - «ascending» - по возрастанию

sortKey="component(d)"
typeдаТип шага. Определяет функциональность данного шага.type="FileSortNode"

Атрибуты FilterNode:

АтрибутОбязательныйОписаниеВозможные значения
idдаНазвание шага для указания в атрибутах ребра fromNode и toNode. Может быть произвольным.id="filter"
guiXнетКоордината верхнего левого угла шага для отрисовки графа в инспекторе заданий.guiX="50"
guiYнетКоордината верхнего левого угла шага для отрисовки графа в инспекторе заданий.guiY="100"
guiNameнетИмя шага, указываемое на графе. Равно type шага. Нельзя изменять.guiName="FilterNode"
Filter expressionдаВыражение, по которому фильтруются записи. Возвращает логическое значение.
<Attr name="filterExpression">
    <![CDATA[
        $in[0].Product == "карандаш"
    ]]>
</Attr>
typeдаТип шага. Определяет функциональность данного шага.type="FilterNode"

Атрибуты FlatFileWriter:

АтрибутОбязательныйОписаниеВозможные значения
idнетНазвание шага для использования в атрибутах ребра fromNode и toNode.id="writer"
guiXнетКоордината верхнего левого угла шага для отрисовки графа в инспекторе заданий.guiX="50"
guiYнетКоордината верхнего левого угла шага для отрисовки графа в инспекторе заданий.guiY="100"
guiNameнетИмя шага, указываемое на графе. Равно type шага. Нельзя изменять.guiName="FlatFileWriter"
file URLдаПуть к файлу, в который должен быть записан результирующий набор данных.${WRITE_DIR}/out.txt
typeдаТип шага. Определяет функциональность данного шага.type="FlatFileWriter"