.. _smev_ql_func: Функции СМЭВ QL Сервера ^^^^^^^^^^^^^^^^^^^^^^^^^^ Администрирование и конфигурирование ###################################### Создание СМЭВ QL Сервера """"""""""""""""""""""""""" Данная функция позволяет создать рабочий экземпляр СМЭВ QL сервера с помощью команды, выполняемой утилитой. .. table:: Настраиваемые параметры +----------+-----------------------------------------------+--------------------------------------------------------+ | Параметр | Описание | Где задается | +==========+===============================================+========================================================+ | app name | Имя создаваемого экземпляра СМЭВ QL сервера. | в командной строке: | | | Параметр является обязательным для заполнения | ``java -jar smevql-server-all.jar new `` | +----------+-----------------------------------------------+--------------------------------------------------------+ **Предварительное состояние:** 1. Развернут дистрибутив СМЭВ QL сервер. 2. Запущена консоль утилиты для работы со СМЭВ QL. **Результирующее состояние:** 1. Создана первичная структура папок и файлов СМЭВ QL. 2. Ошибка выполнения команды. **Сценарий выполнения** 1) Администратор сервера в консоли вводит команду создания нового экземпляра СМЭВ QL с указанием имени: ``java -jar smevql-server-all.jar new `` 2) Система выполняет создание экземпляра СМЭВ QL сервера с заданным именем: - если во время выполнения команды возникла ошибка, то сценарий завершается с результирующим состоянием 2; - иначе, команда выполнена успешно, создана первичная структура папок и файлов, завершение сценария с результирующим состоянием 1. **Результирующее состояние:** 1. СМЭВ QL сервер успешно запущен, создана первичная структура папок и файлов. 2. Ошибка выполнения команды. **Первичная структура папок и файлов** .. table:: Первый уровень вложенности корневой папки **smevql** +------------------+-----------+-------------------------------------------------+---------------------+ | Название | Тип | Описание | Уровень вложенности | +==================+===========+=================================================+=====================+ | application.yaml | yaml-file | Файл с описанием настроек СМЭВ QL сервер | 1 | | | | (:numref:`smev_ql_config`) | | +------------------+-----------+-------------------------------------------------+---------------------+ | credentials.yaml | yaml-file | Файл с описанием представления СМЭВ QL | 1 | | | | сервер (:numref:`smev_ql_config`) | | +------------------+-----------+-------------------------------------------------+---------------------+ | logs | folder | Папка с лог-файлами СМЭВ-QL сервер | 1 | +------------------+-----------+-------------------------------------------------+---------------------+ | models | folder | Папка с описанием моделей данных | 1 | +------------------+-----------+-------------------------------------------------+---------------------+ | readme.md | md-file | read-файл в формате markdown, описывает | 1 | | | | основные функции СМЭВ QL | | +------------------+-----------+-------------------------------------------------+---------------------+ | smevql.jar | jar-file | Jar-файл с кодом СМЭВ QL | 1 | +------------------+-----------+-------------------------------------------------+---------------------+ | sources | folder | Папка с описанием источников данных | 1 | +------------------+-----------+-------------------------------------------------+---------------------+ | states | folder | Папка с описанием машин состояний | 1 | +------------------+-----------+-------------------------------------------------+---------------------+ | openapi.yaml | yaml-file | Файл с первичной спецификацией Open API СМЭВ QL | 1 | +------------------+-----------+-------------------------------------------------+---------------------+ .. table:: Содержимое папки **models** +---------------------+-----------+----------------------------------------------+---------------------+ | Название | Тип | Описание | Уровень вложенности | +=====================+===========+==============================================+=====================+ | base | folder | Папка с версиями описания структуры базовой | 2 | | | | модели данных | | +---------------------+-----------+----------------------------------------------+---------------------+ | current (symlink) | symlink | Ссылка на папку модели по умолчанию | 3 | +---------------------+-----------+----------------------------------------------+---------------------+ | 1.0 | folder | Папка с версией базовой модели данных | 3 | +---------------------+-----------+----------------------------------------------+---------------------+ | model | yaml-file | Файл с описанием базовой модели данных | 4 | +---------------------+-----------+----------------------------------------------+---------------------+ Содержимое папки **sources** По умолчанию, пустая папка, содержимое заполняется в процессе создания моделей источников. .. table:: Содержимое папки **logs** +----------------------+----------+------------------+---------------------+ | Название | Тип | Описание | Уровень вложенности | +======================+==========+==================+=====================+ | environment_name.log | log-file | Лог-файл СМЭВ QL | 2 | +----------------------+----------+------------------+---------------------+ Содержимое папки **states**: по умолчанию, пустая папка, содержимое заполняется в процессе создания машин-состояний. Конфигурирование СМЭВ-QL сервер """""""""""""""""""""""""""""""""" Пример конфигурации файла ``application.yml`` для СМЭВ QL сервера см. в разделе :numref:`smev_ql_config` Руководства администратора. Запуск, остановка, перезапуск приложения СМЭВ QL сервер """""""""""""""""""""""""""""""""""""""""""""""""""""""""" Примеры команд и их описание приведено в :numref:`quick_start`. .. _openapi_smevql: OpenAPI СМЭВ-QL """""""""""""""""""""""""" Общее описание **************** Обращение потребителей данных или иных внешних систем к СМЭВ QL серверу происходит путем вызова REST-методов. Первичная спецификация Open API СМЭВ QL сервера поставляется в исходном дистрибутиве, которая в дальнейшем может обновляться на основании модели данных и модели машины-состояний. Спецификация Open API хранится в файловой системе СМЭВ QL сервера по пути: ``smevql/openapi.yaml`` Описание спецификации ********************************* .. table:: Описание спецификации +-------------------+--------------------------------------------+-------------------------------------------------------------------+ | **Группа** | **Метод** | **Назначение** | +===================+============================================+===================================================================+ | States | GET/states | Получить описание всех моделей машин состояний | | +--------------------------------------------+-------------------------------------------------------------------+ | (работа с моделью | GET/states/{model} | Получить описание конкретной модели машины состояний | | машины состояний) +--------------------------------------------+-------------------------------------------------------------------+ | | POST/states/{model}/{event} | Изменить статус (состояние) машины состояний. Спецификация | | | | метода строится на основании заполненной карты машины состояний. | +-------------------+--------------------------------------------+-------------------------------------------------------------------+ | Model | GET/model | Получить описание всех моделей данных | | +--------------------------------------------+-------------------------------------------------------------------+ | (работа с моделью | GET/model/{model} | Получить описание конкретной модели данных | | данных) +--------------------------------------------+-------------------------------------------------------------------+ | | GET/model/{model}/{version} | Получить описание конкретной версии модели данных | | +--------------------------------------------+-------------------------------------------------------------------+ | | GET/server/indexes/required | Получить список рекомендованных для создания индексов полей. | | | | Строится на используемых в связях моделей (connections) и блоке | | | | ``conditions.allowed`` моделей | +-------------------+--------------------------------------------+-------------------------------------------------------------------+ | Sources | GET/sources | Получить описание модели источников | | | | | | (работа с моделью | | | | источников) | | | +-------------------+--------------------------------------------+-------------------------------------------------------------------+ | Data | GET/data/{token} | Запрос данных в асинхронном режиме по токену | | +--------------------------------------------+-------------------------------------------------------------------+ | (работа с данными | GET/certificaties | Получить сертификат для проверки цифровой подписи на стороне | | поставщика) | | клиента | | +--------------------------------------------+-------------------------------------------------------------------+ | | POST/data | Ключевой запрос получения данных поставщика. Схема запроса по | | | | умолчанию не содержит объекты витрины, а обновляется отдельной | | | | процедурой на основании заполненной модели данных | | | | (:numref:`data_model`). | | +--------------------------------------------+-------------------------------------------------------------------+ | | POST/regulated-query | Выполнение СМЭВ QL РЗ | +-------------------+--------------------------------------------+-------------------------------------------------------------------+ | Push | POST/push/consumer/create | Зарегистрировать нового потребителя на получение уведомлений при | | | | изменении данных витрины | | (управление +--------------------------------------------+-------------------------------------------------------------------+ | рассылками на | GET/push/consumer | Получить список всех потребителей, зарегистрированных на | | изменения данных | | получение уведомлений при изменении данных витрины | | витрины) +--------------------------------------------+-------------------------------------------------------------------+ | | GET/push/consumer/resources/{agent_target} | Получить список ресурсов, изменения которых, отслеживает заданный | | | | потребитель | | +--------------------------------------------+-------------------------------------------------------------------+ | | GET/push/consumer/agent_targets/{resource} | Получить список потребителей, которые отслеживают изменения | | | | заданного ресурса | | +--------------------------------------------+-------------------------------------------------------------------+ | | POST/push/consumer/delete/resource | Удалить отслеживание изменений конкретного ресурса для заданного | | | | потребителя | | +--------------------------------------------+-------------------------------------------------------------------+ | | POST/push/consumer/delete/ | Удалить отслеживание изменений всех ресурсов для заданного | | | | потребителя | +-------------------+--------------------------------------------+-------------------------------------------------------------------+ | Прочие служебные | GET/ping | Проверить сетевую доступность СМЭВ QL сервер | | методы | | | +-------------------+--------------------------------------------+-------------------------------------------------------------------+ | События | POST/in-event | Зарегистрировать новое событие | +-------------------+--------------------------------------------+-------------------------------------------------------------------+ Подробное описание всех эндпоинтов в :numref:`endpoints`. .. _update_openapi_data_model: Обновление OpenAPI на основании изменений модели данных ************************************************************ Для применения изменений модели (или применения новой модели) данных в Open API СМЭВ QL необходимо выполнить следующие действия: 1. Администратор системы выполняет команду запуска или перезапуска приложения (подробнее см. :numref:`quick_start`) 2. Система определяет актуальную версию модели (старшая по номеру или версия явно указанная в ``current symlink``). 3. Система дополняет схемы OpenAPI атрибутами из модели. 4. Система сохраняет обновленные данные Open API **только в оперативной памяти** (локальный файл ``openapi.yaml`` не меняется). Для того, чтобы изменения модели были применены в локальном файле ``openapi.yaml``, необходимо выполнить следующие действия: 1. Администратор системы выполняет в консоли команду генерации OpenAPI: .. code-block:: bash yaml g openapi model 2. Система определяет актуальную версию модели данных (старшая по номеру или версия явно указанная в ``current symlink``) 3. Система дополняет схемы OpenAPI атрибутами из модели. 4. Система обновляет локальный файл ``openapi.yaml``. Регистрация OpenAPI СМЭВ QL в СМЭВ4 """""""""""""""""""""""""""""""""""""""""""" Для возможности использования СМЭВ QL сервер, необходимо выполнить регистрацию OpenAPI в СМЭВ4 через ЕИП НСУД и выдать права доступа потребителям на выполнение запросов вида - Обмен с использованием регламентированных запросов типа «Rest-сервис» в системе ЛК УВ. При регистрации REST-интерфейса потребуется указать следующие ключевые атрибуты: 1. Мнемоника информационной системы поставщика данных. 2. Указание префикса url REST-интерфейса СМЭВ QL сервер, например: ``smevql/api/v1`` 3. Приложить заполненный файл openapi.yaml (:numref:`openapi_smevql`) Работа с моделями #################### .. _base_model_create: Создание базовой модели """""""""""""""""""""""""""" Общее описание *************** :ref:`basic_data_model` автоматически генерируется при создании СМЭВ QL и не должна редактироваться вручную. Базовая модель служит для унификации описания типов данных и позволяет значительно сокращать описание атрибутов ресурса в модели данных (:ref:`data_model`). Пример описания атрибута в модели данных без применения базовой модели: .. code-block:: yaml id: name: Идентификатор type: - string - STRING length: 0 nullable: null key: NONE Пример описания атрибута в модели данных c применением базовой модели: .. code-block:: yaml id: *ds Общий сценарий выполнения **************************** 1. Администратор сервера в консоли вводит команду создания экземпляра СМЭВ QL сервер: .. code-block:: yaml java -jar smevql-server-all.jar new (new-app-name) 2. Система создаёт новую версию папки и файла базовой модели с заполненным содержимым - ``model.yaml`` .. _base_model_create_img: .. figure:: /_static/img/modules/smevql/base_model_create.png :align: center :alt: Создание базовой модели Создание базовой модели Описание базовой модели ************************ .. code-block:: yaml default_string: &ds name: Строка type: - string - STRING length: 0 nullable: NULL key: NONE source: NONE default_number: &dn name: Число type: - integer - INTEGER length: 0 nullable: NULL key: NONE source: NONE primary_key: &pk name: Ключ type: - string - STRING length: 0 nullable: NULL key: PRIMAY source: NONE static_value: &sv name: Статическое значение type: - string - STRING length: 0 nullable: NULL key: NONE source: STATIC //зарезервированное значение default_value: Значение //статическое значение без извлечения env_value: &ev name: Значение из окружения type: - string - STRING length: 0 nullable: NULL key: NONE source: ENV //зарезервированное значение default_value: Значение если нет переменной окружения env_key: ключ_переменной_окружения base_model: &base_model default_fields: &default_fields Генерация модели данных """""""""""""""""""""""""" Общее описание **************** Данная функция позволяет сгенерировать новую пустую :ref:`data_model`. Сценарий выполнения ******************** 1. Администратор сервера в консоли вводит команду генерации новой модели данных с обязательным указанием названия модели: .. code-block:: bash ./smevql g model 2. Система проверяет, что имя модели уникально: a. если имя модели не уникально (модель данных с таким именем уже существует в файловой системе СМЭВ QL), то Система выводит соответствующее сообщение об ошибке. b. иначе, имя модели уникально, переход к выполнению следующего шага. 3. Система создаёт папку с указанным наименованием и файл ``model.yaml`` 4. Далее Администратор сервера вручную заполняет модель данных требуемыми значениями. Для генерации модели на основе другого источника, использующего подключение к ПО Prostore используется команда: .. code-block:: bash ./smevql schema-gen -ds -d Без указания параметра ``-ds`` будет формироваться модель на основе источника с названием Prostore. Описание модели данных *********************** .. table:: Описание модели данных .. rst-class:: longtable +------------------+-------------------------------------------------------------+----------------------------------------+ | Элемент модели | Описание | Пример | +==================+=============================================================+========================================+ | - name: | Название модели данных | smevql | +------------------+-------------------------------------------------------------+----------------------------------------+ | version: | Номер версии модели данных | 1.0 | +------------------+-------------------------------------------------------------+----------------------------------------+ | resources: | Описание ресурсов модели данных | :ref:`resources` | +------------------+-------------------------------------------------------------+ | | : | Техническое название ресурса. Должно быть уникальным в | | | *base_model | рамках модели данных, т.к. используется для указания связей | | +------------------+-------------------------------------------------------------+ | | name: | Название ресурса на русском языке | | +------------------+-------------------------------------------------------------+ | | description: | Дополнительное описание ресурса, обычно указывается его | | | | бизнес-смысл | | +------------------+-------------------------------------------------------------+ | | fields: | Список полей ресурса. Для каждого поля указывается: | | | | | | | | - название поля; | | | | | | | | - тип данных (возможные типы данных определены в | | | | :numref:`basic_data_model`); | | | | | | | | - опционально источник данных (source) в том случае, если | | | | он отличается от источника данных всего ресурса; | | | | - опционально ограничение на вывод данного поля в | | | | результатах запроса (:ref:`guard`:). | | +------------------+-------------------------------------------------------------+----------------------------------------+ | connections: | Описание связей между ресурсами по заданным ключам | :ref:`connections` | +------------------+-------------------------------------------------------------+ | | belongs_to: | | | +------------------+-------------------------------------------------------------+ | | has_many: | | | +------------------+-------------------------------------------------------------+----------------------------------------+ | conditions: | Описание ограничений на использование полей в | :ref:`conditions` | | | пользовательских запросах | | +------------------+-------------------------------------------------------------+ | | allowed: | Если заполнено, то поиск разрешен только по этим полям и | | | | полям с ключами | | +------------------+-------------------------------------------------------------+ | | denied: | Если заполнено, то поиск запрещен по этим ключам | | +------------------+-------------------------------------------------------------+ | | always: | Наличие условий в блоке ``always`` должно ко всем запросам | | | | ресурса добавлять эти условия, если указаны в запросе, то | | | | перетирать | | +------------------+-------------------------------------------------------------+----------------------------------------+ | extract: | Указание источника данных для ресурса | :ref:`extract` | +------------------+-------------------------------------------------------------+ | | name: | Название (мнемоника) источника данных | | +------------------+-------------------------------------------------------------+ | | table: | Название таблицы в схеме БД источника | | +------------------+-------------------------------------------------------------+----------------------------------------+ | conditions: | Массив условий применения источника на основании значений | :ref:`conditions_and` | | | полученных в запросе атрибутов. | | | | | | | | Все условия внутри источника действуют через | | | | **логическое И (AND)**. | | | | | | | | Если запрос подходит под два и более источников , то данные | | | | **извлекаются и объединяются из всех подходящих**. | | +------------------+-------------------------------------------------------------+----------------------------------------+ | fetch: | Режим получения данных (синхронный или асинхронный). | :ref:`fetch` | | | Содержит атрибуты: | | | | | | | | - policy - режим работы, поддерживается режимы | | | | ``sync | async | async_on_timeout`` (значение по | | | | умолчанию sync); | | | | | | | | - timeout - таймаут получения данных клиента (значение по | | | | умолчанию PT20S); | | | | | | | | - store_timeout - время хранения временных данных для | | | | асинхронного режима работы (значение по умолчанию PT15M); | | | | | | | | - retries - число попыток получения данных (значение по | | | | умолчанию 1). | | +------------------+-------------------------------------------------------------+----------------------------------------+ .. _guard: Пример блока ``fields`` ************************** .. code-block:: yaml fields: <<: *default_fields first_name: *ds last_name: <<: *ds guard: [last_name] snils: <<: *ds guard: [last_name first_name snils] .. _resources: Пример блока ``resources`` ******************************* .. code-block:: yaml resources: # slots — техническое название модели, по нему производятся все связи - slots: *base_model # значение name — название модели на русском языке name: Слоты # description - дополнительное описание ресурса description: таблица с указанием доступных и занятых временных интервалов # fields — список полей модели fields: # список полей может включать перечень полей из default_fields <<: *default_fields # поля по-умолчанию наследуются от ds (default_string) из базовой модели id: *ds resource_id: *ds # у поля может быть переопределен source (по-умолчанию у каждого поля источник всей модели) type: *ds source: field: tag_type age: *ds source: field: tag_age visitTime: *ds duration: *ds status: *ds create_ts: *ds update_ts: *ds update_ts: *ds .. _connections: Пример блока ``connections`` ******************************** .. code-block:: yaml connections: belongs_to: - resource: primary_key: [ id ] foreign_key: [ resource_id ] has_many: - book: primary_key: [ id ] foreign_key: [ slot_id ] - unaccessible_period: primary_key: [ resource_id, type ] foreign_key: [ resource_id, type ] .. _conditions: Пример блока ``conditions`` ******************************** .. code-block:: yaml conditions: allowed: [id, name] # если заполнено, то поиск разрешен только по этим полям и полям с ключами denied: [snils] # если заполнено, то поиск запрещен по этим ключам always: # наличие условий в блоке always должно ко всем запросам ресурса добавлять эти условия, если указаны в запросе, то перетирать - region: ["=", "77"] - blocked: ["=", true] .. _extract: Пример блока ``extract`` ************************** .. code-block:: yaml extract: source: - name: prostore table: misdm.slots .. _conditions_and: Пример блока ``conditions`` ****************************** .. code-block:: yaml extract: source: - name: prostore1 table: misdm.slots conditions: # попадание в промежуток - range: field: age from: 0 to: 2 - eq: field: color not: "blue" - name: prostore2 table: misdm.39slots conditions: # ограничения по (не)равенству - eq: field: resource_id is: 1 - name: prostore3 table: misdm.39slots conditions: # ограничения по наличию в источнике - eq: field: snils extract: source: redis table: default_table key: resource_hashed_id algorithm: md5 # select count(*) > 0 from offices.offices where resource_hashed_id = ? # параметр: md5(snils) is: true - name: prostore_default table: misdm.39slots conditions: - fallback: true .. _fetch: Пример блока ``fetch`` ************************* .. code-block:: yaml fetch: policy: sync | async | async_on_timeout # на данном этапе реализуется только sync store_timeout: PT15M timeout: PT20S retries: 2 Автоматическое создание модели данных на основе схемы БД """""""""""""""""""""""""""""""""""""""""""""""""""""""""" Общее описание ****************** Данная функция позволяет создать заполненную модель данных, на основе схемы БД подключенного источника (на основе схемы данных Prostore). Сценарий выполнения ******************* **Предварительные условия:** 1. Настроена модель источника данных типа Prostore (:numref:`data_source_model_create`). 2. Создана базовая модель (:numref:`base_model_create`). **Ход выполнения:** 1. Администратор сервера в консоли вводит команду генерации модели данных на основе схемы БД источника Prostore: .. code-block:: bash ./smevql schema-gen -d <название схемы> 2. Система проверят наличие базовой модели: a. если базовая модель отсутствует, то Система выводит соответствующее сообщение об ошибке; b. иначе, переход к выполнению следующего шага; 3. Система проверяет, что имя модели (название схемы) уникально: a. если имя модели не уникально (модель данных с таким именем уже существует в файловой системе СМЭВ QL), то Система выводит соответствующее сообщение об ошибке; b. иначе, имя модели уникально, переход к выполнению следующего шага; 4. Система создаёт папку с указанным наименованием и файл ``model.yaml``; 5. Система заполняет содержимое файла model.yaml по следующим правилам: a. Каждая таблица в схеме БД - это отдельный ресурс в модели данных; b. Каждый атрибут таблицы в схеме БД - это элемент блока ``fields:`` соответствующего ресурса; c. Блок ``connections:`` - пустой; d. Блок ``conditions:`` - пустой; e. Блок ``extract:`` - ``name: <название источника из модели источника>``, ``table: <название таблицы из БД>``. .. _bd_example: .. figure:: /_static/img/modules/smevql/bd_example.png :align: center :alt: Схема в БД Prostore Схема в БД Prostore Сгенерированная модель данных: .. code-block:: yaml - name: smevql version: 1.0 data: resources: - passenger: *base_model name: Пассажиры description: Логическая таблица "Пассажиры" fields: id: !!merge <<: *ds name: ИД пассажира firstname: !!merge <<: *ds name: Имя lastname: !!merge <<: *ds name: Фамилия connections: extract: source: - name: prostore table: ms.passengers - trip: *base_model name: Рейс description: Логическая таблица "Рейс" fields: !!merge <<: *default_fields id: !!merge <<: *ds name: ИД рейса number: !!merge <<: *pkn name: Номер duration: !!merge <<: *dtm name: В пути connections: extract: source: - name: prostore table: ms.trips Создание новой версии модели данных """""""""""""""""""""""""""""""""""""" Общее описание **************** СМЭВ QL может одновременно использовать несколько разных моделей данных с разным наименованием. Однако в рамках одного наименования модели (папки с названием модели) может быть активна только одна версия модели данных. Версия модели данных характеризуется уникальным номером и наличием отдельной папки с данным номером в файловой системе СМЭВ QL. .. _data_model_version: .. figure:: /_static/img/modules/smevql/data_model_version.png :align: center :alt: Разные версии одной модели Разные версии одной модели Модели данных считываются, валидируются и загружаются в память из папки ``models`` при запуске СМЭВ QL сервера. По умолчанию используется версия ``model``, на которую ссылается ``symlink current``, при его отсутствии по умолчанию считается **старшая по номеру** версия. Модели и версии, **начинающиеся с подчеркивания (_) НЕ загружаются**, они находятся в стадии проектирования. Сценарий выполнения ********************** **Предварительные условия:** 1. Подготовлена модель данных с учетом всех необходимых изменений (файл ``model.yaml``). **Ход выполнения:** 1. Администратор системы выбирает папку с названием модели данных для которой необходимо создать новую версию. 2. Администратор системы вручную создает новую папку с указанием нового номера версии (обычно это новое целочисленное значение). 3. Администратор системы вручную переносит, заранее подготовленный файл model.yaml, в папку с новым номером версии. Проверка валидности модели данных """""""""""""""""""""""""""""""""" Общее описание *************** Валидация модели данных выполняется при каждом запуске СМЭВ QL сервер и в случае возникновения ошибок, приложение не будет запущено. Помимо этого можно предварительно проверить корректность заполнения модели данных путем вызова специальной команды в консоли приложения. Сценарий выполнения ********************** 1. Администратор сервера в консоли вводит команду проверки валидности модели данных: a. если требуется проверить все модели данных, то выполняется команда: ``./smevql test model all``. b. если требуется проверить конкретные модели, то выполняется команда (с указанием через запятую) наименований моделей: ``./smevql test model , ``. 2. Система проверяет корректность заполнения моделей данных и в случае наличия ошибок выведет соответствующее сообщение. .. _data_type_mapping: Маппинг типов данных СМЭВ QL - Prostore """""""""""""""""""""""""""""""""""""""""" .. table:: Маппинг типов данных СМЭВ QL сервера .. rst-class:: longtable +------------------+-----------------------------------------------------+----------------------+----------------------------+ | Логический тип | Описание | Логический тип СМЭВ | Тип базовой модели СМЭВ QL | | Prostore | | QL | | +==================+=====================================================+======================+============================+ | BOOLEAN | Логический (булевый) тип | BOOLEAN | &db, &pkb | +------------------+-----------------------------------------------------+----------------------+----------------------------+ | CHAR (n) | Строка ограниченной длины (n символов). Размерность | STRING | &ds, &dst, &denv, &pks | | | строки обязательна | | | +------------------+-----------------------------------------------------+----------------------+----------------------------+ | VARCHAR [(n)] | Строка ограниченной длины (n символов). Размерность | STRING | &ds, &dst, &denv, &pks | | | строки опциональна | | | +------------------+-----------------------------------------------------+----------------------+----------------------------+ | LINK | Строка неограниченной длины. Предназначена для | BINARY | &dbn, &pkbn | | | ссылочных полей | | | +------------------+-----------------------------------------------------+----------------------+----------------------------+ | UUID | Строка ограниченной длины (36 символов) | STRING | &ds, &dst, &denv, &pks | +------------------+-----------------------------------------------------+----------------------+----------------------------+ | INTEGER, алиас — | Целое число фиксированной длины со знаком в | SHORT, INTEGER | &pksh, &dsh, &pkn, &dn | | INT32 | диапазоне от ``-2147483648`` до ``2147483647`` | | | +------------------+-----------------------------------------------------+----------------------+----------------------------+ | BIGINT, алиас — | Целое число фиксированной длины со знаком в | LONG | &pkl, &dl | | INT64 | диапазоне -2\ :sup:`63`, 2\ :sup:`63`-1 [#]_ | | | | | | | | +------------------+-----------------------------------------------------+----------------------+----------------------------+ | DOUBLE | Число с плавающей запятой с двойной точностью | DOUBLE | &dd, &pkd | +------------------+-----------------------------------------------------+----------------------+----------------------------+ | FLOAT | Число с плавающей запятой | FLOAT | &pkf, &df | +------------------+-----------------------------------------------------+----------------------+----------------------------+ | DATE | Дата (без времени суток) | DATE | &ddt, &pkdt | +------------------+-----------------------------------------------------+----------------------+----------------------------+ | TIME, TIME (p) | Время (без даты). | TIME | &dtm, &pktm | | | | | | | | Значение p задает точность отображаемого времени. | | | | | | | | | | Возможные значения: от 0 (секунды) до 6 | | | | | (микросекунды). | | | | | | | | | | Значение по умолчанию - 6. Количество микросекунд | | | | | находится в диапазоне от 0 до 86399999999 | | | +------------------+-----------------------------------------------------+----------------------+----------------------------+ | TIMESTAMP, | Дата и время. | TIMESTAMP | &pkts, &dts | | | | | | | TIMESTAMP (p) | Значение p задает точность отображаемого времени. | | | | | | | | | | Возможные значения: от 0 (секунды) до 6 | | | | | (микросекунды). | | | | | | | | | | Значение по умолчанию - 6 | | | +------------------+-----------------------------------------------------+----------------------+----------------------------+ | | Не поддерживается в Prostore | BYTE | &dbt, &pkbt | +------------------+-----------------------------------------------------+----------------------+----------------------------+ | | Не поддерживается в Prostore | BIG_DECIMAL | &dbd, &pkbd | +------------------+-----------------------------------------------------+----------------------+----------------------------+ .. [#] -2\ :sup:`63` = -9 223 372 036 854 775 808, 2\ :sup:`63`-1 = 9 223 372 036 854 775 807 Работа с источниками данных ################################# .. _data_source_model_create: Создание модели источников """""""""""""""""""""""""""""""""" Общее описание **************** Данная функция позволяет добавлять новую версию описания модели источников данных СМЭВ-QL. В качестве источников данных для СМЭВ-QL сервер могут выступать: 1. REST-интерфейс витрины данных (Prostore); 2. Другой СМЭВ-QL сервер Модель источников данных СМЭВ-QL хранится в файловой системе СМЭВ-QL сервера по пути: ``sources/custom/1.0/source.yaml`` Допускается описание всех источников в рамках одной модели. Общий сценарий выполнения ************************** 1. Администратор сервера в консоли вводит команду генерации новой пустой модели источника: .. code-block:: yaml ./smevql g source 2. Система создаёт новую версию папки и файла модели источника с пустыми значениями - ``source.yaml`` 3. Администратор сервера открывает на редактирование файл модели источника ``source.yaml`` и заполняет параметры необходимыми значениями. .. _source_create: .. figure:: /_static/img/modules/smevql/source_create.png :align: center :alt: Создание модели источников данных Создание модели источников данных Структура source.yaml ************************ Описание источника данных в формате YAML имеет следующую структуру: .. table:: Описание источника данных +---------------------+----------------------------------------------------------------------------------------------------+ | Параметр | Описание | +=====================+====================================================================================================+ | Наименование | Наименование источника данных. | | | | | | В рамках файла ``source.yaml`` источник всегда имеет название с постфиксом ``_source``. | | | | | | При этом именем источника в моделях данных считается часть **без** учета данного постфикса. | | | | | | То есть источник ``egrn_source`` в модели данных ``model.yaml`` необходимо указывать как ``egrn``. | +---------------------+----------------------------------------------------------------------------------------------------+ | type | Тип интеграционного взаимодействия. На текущий момент поддерживается только rest | +---------------------+----------------------------------------------------------------------------------------------------+ | version | | +---------------------+----------------------------------------------------------------------------------------------------+ | adapter | Тип источника данных. Может принимать значения: | | | | | | - prostore; | | | | | | - smevql. | +---------------------+----------------------------------------------------------------------------------------------------+ | protocol | Указание протокола передачи данных. На текущий момент поддерживается только HTTP | +---------------------+----------------------------------------------------------------------------------------------------+ | host | Хост-адрес сервера источника данных | +---------------------+----------------------------------------------------------------------------------------------------+ | port | Порт сервера источника данных | +---------------------+----------------------------------------------------------------------------------------------------+ | path | Путь для вызова REST-метода API источника данных | +---------------------+----------------------------------------------------------------------------------------------------+ | template | Шаблон передачи REST-запроса к источнику | +---------------------+----------------------------------------------------------------------------------------------------+ | payload-path | | +---------------------+----------------------------------------------------------------------------------------------------+ | headers | Значения по умолчанию для заголовка REST-запроса к источнику | +---------------------+----------------------------------------------------------------------------------------------------+ | threads-count | | +---------------------+----------------------------------------------------------------------------------------------------+ | connection-timeout | Тайм-аут ожидания ответа от сервера источника | +---------------------+----------------------------------------------------------------------------------------------------+ Описание источника данных в формате YAML имеет следующую структуру: .. code-block:: yaml prostore_source: type: rest version: 1.0 adapter: prostore protocol: http host: localhost port: 9090 path: api/v1/datamarts/query?format=json template: '{ "query": "%{request}", "queryId": "%{request_id}" }' payload-path: result headers: - accept: application/json - content-type: application/json threads-count: 10 connection-timeout: 0 smevql_server_source: type: rest version: 1.0 adapter: smevql protocol: https host: localhost port: 9091 path: api/query?format=json template: '{ "query": "%{request}" }' payload-path: result headers: - accept: application/json - content-type: application/json Создание новой версии модели источников """""""""""""""""""""""""""""""""""""""""" Общее описание **************** СМЭВ QL может одновременно использовать несколько разных моделей источников с разным наименованием. Однако в рамках одного наименования модели (папки с названием модели) может быть активна только одна версия модели источников. Версия модели источников характеризуется уникальным номером и наличием отдельной папки с данным номером в файловой системе СМЭВ QL. .. _new_source_model_img: .. figure:: /_static/img/modules/smevql/new_source_model.png :align: center :alt: Создание новой версии модели источников данных Создание новой версии модели источников данных Источники данных считываются, валидируются и загружаются в память из папки ``sources`` при запуске СМЭВ QL сервера. По-умолчанию используется версия источника, на которую ссылается ``symlink current``, при его отсутствии по-умолчанию считается **старшая** версия. Источники и версии, **начинающиеся с подчеркивания (_) НЕ загружаются**, они находятся в стадии проектирования. Сценарий выполнения *********************** **Предварительные условия:** 1. Подготовлена модель источников с учетом всех необходимых изменений (файл ``source.yaml``). **Ход выполнения:** 1. Администратор системы выбирает папку с названием модели источников для которой необходимо создать новую версию. 2. Администратор системы вручную создает новую папку с указанием нового номера версии (обычно это новое целочисленное значение). 3. Администратор системы вручную переносит, заранее подготовленный файл source.yaml, в папку с новым номером версии. Проверка доступности источников """""""""""""""""""""""""""""""" Общее описание ****************** Данная функция позволяет проверить сетевую доступность источников, указанных в модели. Сценарий выполнения ******************** 1. Администратор сервера в консоли вводит команду проверки доступности источников: a. если требуется проверить все источники, то выполняется команда: ``./smevql test source all``; b. если требуется проверить конкретный источник, то выполняется команда (с указанием через запятую) наименований источников: ``./smevql test source , ``; 2. Система отправляет проверочный запрос к источнику и дожидается ответа в течении заданного таймаута: a. если ответ не пришёл в течение заданного таймаута, то Система выводит соответствующее сообщение об ошибке, источник не доступен; b. иначе, ответ пришёл в течение заданного таймаута, источник доступен. Работа с картами машин состояний ################################## .. _state_machine_map_create: Создание карты машины-состояний """""""""""""""""""""""""""""""""" Общее описание **************** Карта машины состояний (:numref:`state_machine_concept`) описывает её статусы и события, при вызове которых осуществляется переход к следующему статусу. Карта состояний и переходов машины состояний описывается в виде YAML-файла ``state.yaml`` и хранится в файловой системе СМЭВ QL сервера по пути: ``states>>>state.yaml`` Структура карты машины состояний ******************************** .. table:: Структура карты машины состояний .. rst-class:: longtable +-----------------------+----------------------------------------------------------------------------------------------------------+ | **Элемент** | **Описание** | +=======================+==========================================================================================================+ | model: | Название карты машины состояний (модели стэйт-машины) | +-----------------------+----------------------------------------------------------------------------------------------------------+ | states: | Массив возможных состояний | +-----------------------+----------------------------------------------------------------------------------------------------------+ | state: | Название состояния | +-----------------------+----------------------------------------------------------------------------------------------------------+ | attributes: | Массив атрибутов, описывающих состояние. Каждый атрибут имеет следующие свойства: | | | | | | - ``name`` - название атрибута; | | | | | | - ``value`` - значение атрибута. | +-----------------------+----------------------------------------------------------------------------------------------------------+ | initial: | Признак исходного состояния. | | | | | | Может быть определен только у одного состояния в рамках одной карты машины состояний. | +-----------------------+----------------------------------------------------------------------------------------------------------+ | delete: | Признак, указывающий что при переходе в данное состояние будут удалены данные в соответствии с условиями | | | переданными в блоке ``conditions`` исходного запроса от клиента ``POST/states/{model}/{event}``. | | | | | | При этом значения атрибутов для такого статуса не применимы, они игнорируются. | | | | | | Состояние с данным признаком считается конечным и не может использоваться в разделе from при описании | | | событий. | +-----------------------+----------------------------------------------------------------------------------------------------------+ | static: | Признак, при установке которого не меняется статус, а только передается указанная в описании события | | | часть запроса в блоке confirm к связанному источнику. | +-----------------------+----------------------------------------------------------------------------------------------------------+ | events: | Список событий изменения состояний. | | | | | | Каждое событие вызывается отдельным методом ``POST/states/{model}/{event}`` | | | | | | **Важно! В любой модели машины состояний по умолчанию присутствует event с типом init, хотя он и не | | | описан в явном виде.** | | | | | | **Такое событие является обязательным и при его вызове в витрину добавляется новая запись и | | | устанавливается статус исходного состояния (initial)** | +-----------------------+----------------------------------------------------------------------------------------------------------+ | event: | Название события | +-----------------------+----------------------------------------------------------------------------------------------------------+ | from: | Массив состояний из которых возможен вызов события | +-----------------------+----------------------------------------------------------------------------------------------------------+ | to: | В какое состояние переходит стэйт-машина после наступления события | +-----------------------+----------------------------------------------------------------------------------------------------------+ | hooks: | Массив связанных событий, которые будут выполняться после перехода в заданное состояние. | | | | | | На текущий момент в рамках hook возможен только вызов событий других стэйт-машин. | | | | | | Каждый hook имеет следующие свойства: | | | | | | - ``model`` - название карты машины состояний; | | | | | | - ``event`` - название события. | +-----------------------+----------------------------------------------------------------------------------------------------------+ | confirm: | Вызов внешнего REST-метода. | | | | | | Данное действие выполняется до осуществления перехода в рамках вызванного события. | | | | | | Блок содержит следующие свойства: | | | | | | **Описание запроса:** | | | | | | - ``source`` - название внешнего источника (мнемоника вызываемого источника); | | | | | | - ``endpoint`` - эндпоинт вызываемого REST-метода; | | | | | | - ``method`` - тип вызываемого REST-метода; | | | | | | - ``body`` - указание того, какое содержимое body необходимо передать при выполнении REST-запроса | | | внешнему источнику. | | | Возможные значения: ``full``, ``state``, ``conditions``, ``payload``, ``credentials``. | | | | | | Источником для содержимого является соответствующий блок данных в body исходного запроса от | | | клиента (``POST/states/{model}/{event}``). | | | | | | **Описание ответа:** | | | | | | - ``accept`` - описание условия ответа, при соблюдении которого вызов внешнего REST-метода считается | | | успешным. | | | | | | Если данное условие (получение заданного ответа) не выполняется, то переход стэйт-машины завершается | | | ошибкой. Блок содержит следующие свойства: | | | | | | - ``jsonpath`` - получаемый в ответе атрибут; | | | | | | - ``eq`` - значение получаемого атрибута. | | | | | | - ``enrich`` - указание необходимости обновления данных на основании полученного ответа. | | | | | | Блок содержит следующие свойства: | | | | | | - ``allow`` - признак, указывающий о необходимости обновления данных (``true`` - обновлять; ``false`` -| | | только извлекать, без обновления ресурса); | | | | | | - ``jsonpath`` - указание того, из какой части ответа брать данные. | | | | | | При отсутствии объекта по пути ``jsonpath`` в ``confirm`` запросе возвращается ошибка 501 | | | "Отсутствует объект при обращении по jsonpath", выполнение запроса прерывается. | | | | | | - ``attributes`` - массив атрибутов, которые необходимо взять из ответа. | | | | | | Если массив пустой ``[]``, то берутся все атрибуты из указанного ``jsonpath``. | | | | | | При несоответствии атрибутов в блоке ``attributes`` и в ``jsonpath`` - в **payload** вернутся только | | | те атрибуты, по которым есть соответствия с фиксацией в логах событий уровня WARN о | | | несоответствующих атрибутах: ``Отсутствует атрибут *attribute_name" в $.update.payload``. | | | | | | В случае, если в **payload** присутствуют атрибуты, аналогичные тем, что возвращаются при выполнении | | | блока ``enrich``, обновляются данные в соответствии со значениями вернувшимися при выполнении блока | | | ``enrich``. | | | | | | В этом случае в логах фиксируется запись ``"Изменение значений атрибутов: *attribute_name" payload | | | в соответствии со значениями блока enrich"``. | | | | | | Атрибуты **payload** ответа **confirm** обогащают **payload** основного запроса. | | | | | | Обновление данных в витрине в случае обогащения **payload** дополнительными атрибутами происходит | | | независимо от значения updatable. | +-----------------------+----------------------------------------------------------------------------------------------------------+ | updatable: | Признак, указывающий, что необходимо обновить ресурс в рамках вызываемого события | +-----------------------+----------------------------------------------------------------------------------------------------------+ | updatable_attributes: | Массив атрибутов, которые необходимо обновить в рамках вызываемого события. | | | Если массив пустой ``[]``, то обновляются все атрибуты. Источником данных для обновления является блок | | | ``payload`` исходного запроса от клиента (``POST/states/{model}/{event}``) | +-----------------------+----------------------------------------------------------------------------------------------------------+ Пример структуры карты машины состояний: .. code-block:: yaml model: slot # имя модели states: # массив состояний объекта - state: available # название состояния available attributes: # массив атрибутов, описывающих состояние - name: status # состояние определятся значением атрибута status value: AVAILABLE # значение атрибута для описываемого состояния initial: true - state: booked attributes: - name: status value: RECORDED - state: reserved attributes: - name: status value: RESERVED - state: cancelled attributes: - name: status value: CANCELED - state: blocked attributes: - name: status value: BLOCKED - state: deleted delete: true events: # список событий изменения состояний, из них создаются методы API - event: book # создает метод POST /states/slot/book from: # массив состояний из которых возможен вызов события - available - reserved to: booked # в какое состояние переводится объект после события hooks: # массив связанных событий - model: book # после перевода надо вызвать событие init для модели book event: init confirm: source: rmis_rest # названия источника endpoint: /booking/book method: post body: payload # что включать в тело запроса (full|state|conditions|payload|credentials) accept: # условие принятия jsonpath: $.status.statusCode eq: 0 # ожидаем, что statusCode будет равен 0 enrich: allow: true // по умолчанию false attributes: [] // пустой массив — все, а если перечислены, то только эти jsonpath: $.update.payload // ожидается что по этому адресу объект с атрибутами и значениями - event: reserve from: available to: reserved updatable: true // по умолчанию false для всех, кроме init, возможность изменять запись при переводе статуса updatable_attributes: [] // массив атрибутов, которые можно обновлять, пустой — можно все - event: block from: available to: blocked - event: cancel from: - available - reserved - booked - blocked to: cancelled hooks: - model: book event: cancel - event: delete from: - available - reserved - booked - blocked - cancelled to: deleted hooks: # массив связанных событий - model: book # после перевода надо вызвать событие delete для модели book event: delete Сценарий выполнения ******************** 1. Администратор системы в произвольном текстовом редакторе создает и заполняет файл (``state.yaml``) с описанием карты машины состояний. 2. Администратор системы создает папку с названием модели стэйт-машины в рамках каталога ``states``. 3. Администратор системы создает папку с указанием номера версии модели стэйт-машины в рамках каталога с названием стэйт-машины. 4. Администратор системы вручную переносит, заранее подготовленный файл ``state.yaml``, в папку с новым номером версии. 5. Для возможности вызова API методов новой карты машины состояния необходимо обновить openAPI СМЭВ QL (:numref:`update_openapi_data_model`) .. _state_machine_card_img: .. figure:: /_static/img/modules/smevql/state_machine_card.png :align: center :alt: Создание карты машины-состояний Создание карты машины-состояний Создание новой версии карты машины-состояний """""""""""""""""""""""""""""""""""""""""""""""" Общее описание **************** СМЭВ QL может одновременно использовать несколько разных моделей стэйт-машин с разным наименованием. Однако в рамках одного наименования модели (папки с названием модели) может быть активна только одна версия модели стэйт-машины. Версия модели стэйт-машины характеризуется уникальным номером и наличием отдельной папки с данным номером в файловой системе СМЭВ QL. .. _new_state_machine_img: .. figure:: /_static/img/modules/smevql/new_state_machine.png :align: center :alt: Создание новой версии карты машины-состояний Создание новой версии карты машины-состояний Карты машин состояний считываются, валидируются и загружаются в память из папки ``states`` при запуске СМЭВ QL сервера. По-умолчанию используется версия стэйт-машины, на которую ссылается ``symlink current``, при его отсутствии по-умолчанию считается **старшая** версия. Карты машин состояний и версии, **начинающиеся с подчеркивания (_) НЕ загружаются**, они находятся в стадии проектирования. Сценарий выполнения ********************** **Предварительные условия:** 1. Подготовлена модель стэйт-машины с учетом всех необходимых изменений (файл ``state.yaml``). **Ход выполнения:** 1. Администратор системы выбирает папку с названием стэйт-машины для которой необходимо создать новую версию. 2. Администратор системы вручную создает новую папку с указанием нового номера версии (обычно это новое целочисленное значение). 3. Администратор системы вручную переносит, заранее подготовленный файл state.yaml, в папку с новым номером версии. 4. Администратор перезапускает сервер (:numref:`quick_start`). .. _query_post_data: Обработка запроса к витрине ######################################################### Запрос получения данных из витрины (POST/data) """""""""""""""""""""""""""""""""""""""""""""" Общее описание *************** Для выполнения запроса к СМЭВ QL серверу на получение данных витрины (или нескольких витрин, если запрос распределенный (:numref:`disturbed_query`)) потребитель должен вызвать опубликованный метод ``POST/data``. В рамках запроса необходимо передать в теле JSON-объект заданного формата. :ref:`post_data` содержит подробное описание. Запрос изменения данных витрины через события машины состояний (POST/states/{model}/{event}) """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" Для выполнения запроса к СМЭВ QL сервер на изменение данных витрины через машину состояний потребитель должен вызвать опубликованный метод ``POST/states/{model}/{event}``, где ``model`` - название карты машины состояний, а ``event`` - событие карты машины состояний. В рамках запроса необходимо передать в теле JSON-объект заданного формата. В рамках вызова событий машины состояний можно выполнять следующие действия: - Изменить статус машины состояния без обновления данных витрины; - Обновить данные витрины (добавить новые, изменить текущие); - Удалить данные витрины; - Вызывать событие другой машины состояния; - Добавить/обновить/удалить данные другой витрины. :ref:`post_states_model_event` содержит подробное описание. .. _data_request_process: Обработка запроса получения данных витрины """""""""""""""""""""""""""""""""""""""""""""" Общее описание **************** При поступлении запроса от Потребителя на получение данных к СМЭВ QL сервер запускается процесс его обработки, который можно условно разделить на 4 этапа: 1. Проверка запроса и доступов. 2. Формирование плана исполнения запроса. 3. Исполнение плана запроса. 4. Передача ответа потребителю. Для возможности получения данных Потребителем должны быть соблюдены следующие предварительные условия: 1. Модель данных СМЭВ QL сервера успешно создана. 2. Зарегистрирован метод получения данных витрины ``POST/data``. 3. Потребитель обладает правами на выполнение REST-запроса. Проверка запроса и доступов ******************************* .. _query_check_img: .. figure:: /_static/img/modules/smevql/query_check.jpg :align: center :alt: Проверка запроса и доступов Проверка запроса и доступов **Запускающее событие:** - Получен запрос получения данных витрины (вызван метод ``POST/data``) **Ход выполнения:** 1. СМЭВ QL (далее Система) проверяет тело запроса на соответствие заданной схеме (:ref:`query_post_data`): a. если запрос не соответствует заданной схеме, то Система передаёт соответствующее сообщение об ошибке, процесс завершается; b. иначе, формат запроса корректен, переход к выполнению следующего шага. 2. Система проверяет доступ ИС Потребителя к данным витрины, для этого сравнивает полученный в запросе идентификатор системы-потребителя (блок ``credentials->system``) c перечнем запрещенных и разрешенных, который задается в конфигурационном файле приложения ``application.yaml`` (``black_list`` и ``white_list``): a. если доступ запрещен, то Система передаёт соответствующее сообщение об ошибке, процесс завершается; b. иначе, доступ разрешен, переход к выполнению следующего шага. 3. Система получает из блока персистентности Redis текущие значения лимитов на выполнение запросов. 4. Система проверяет превышение установленных лимитов на выполнение запроса Потребителя к заданным ресурсам. Для этого сравнивает текущие полученные значения на шаге 3 с настройками лимитов, определенных в конфигурационном файле приложения ``application.yaml`` (``limits``): a. если допустимый лимит превышен, то Система передаёт соответствующее сообщение об ошибке, процесс завершается; b. иначе, лимиты не превышены, переход к выполнению этапа "Формирование плана исполнения запроса". Формирование плана исполнения запроса *************************************** .. _query_plan_img: .. figure:: /_static/img/modules/smevql/query_plan.jpg :align: center :alt: Формирование плана исполнения запроса Формирование плана исполнения запроса **Запускающее событие:** - Запрос получения данных витрины прошел необходимые проверки. **Ход выполнения:** 1. Система на основании вложенности ресурсов, заданной в запросе (query) определяет уровни плана выполнения запроса и sql-выражения. Формирование плана запроса основывается на внешнем объединении данных в сторону основной сущности. Порядок формирования плана запроса: - на основе query определяется основная запрашиваемая сущность - на основе query определяются вспомогательные сущности - на основе query определяются conditions к основной сущности - на основе query определяются conditions к вспомогательным сущностям - на первом уровне плана формируется запрос к основной сущности на основе: - запрошенных атрибутов - данных модели - условий фильтрации Отмечаются поля, составляющие PK. Первичные ключи, даже отсутствующие в атрибутах запроса к серверу должны быть в запросе к источнику. - формируется запрос к вспомогательным сущностям на основе: - запрошенных атрибутов - данных модели - условий фильтрации - с добавлением фильтрации по PK основной или предшествующей сущности Первичные ключи, даже отсутствующие в атрибутах запроса к серверу должны быть в запросе к источнику, за исключением терминальных запросов. Пример уровней плана на основе запроса: .. _query_plan_lebels_img: .. figure:: /_static/img/modules/smevql/query_plan_levels.png :align: center :alt: Формирование плана исполнения запроса Формирование плана исполнения запроса 2. Система проверяет, что все ресурсы из плана запроса определены в модели данных: a. если хотя бы один ресурс не описан в модели данных, то Система передаёт соответствующее сообщение об ошибке, процесс завершается; b. иначе, все ресурсы описаны в модели данных, переход к выполнению следующего шага. 3. Система проверяет, что для каждого ресурса определён источник получения данных. Для этого по каждому ресурсу определяет его источник в модели данных (блок ``extract:``), в т.ч. с учетом условий применения источника (``extract->conditions:``) и описан ли источник в модели source: a. если хотя бы один источник данных не определен в модели данных или не описан в модели источников, то Система передаёт соответствующее сообщение об ошибке, процесс завершается; b. иначе, для каждого ресурса определен источник данных, переход к выполнению следующего шага. 4. Система определяет стратегию делегирования подзапросов (подзапросов более низкого уровня). Для этого определяет значение в параметре ``request→strategy`` конфигурационного файла приложения ``application.yaml`` (делегирование возможно только источнику smevql): a. если значение ``atomic`` - то последовательность выполнения подзапросов соответсвует иерархии уровней, определенной на шаге 1; b. иначе установлено значение delegate - делегирование подзапроса со всеми дочерними элементами другому СМЭВ QL. В таком случае, все делегированные подзапросы исключаются из плана запроса данного СМЭВ QL. 5. Система проверяет, что в модели данных (блок connections:) существуют и корректно заполнены связи между всему основными и подчиненными ресурсами: a. если хотя бы одна связь между основным и подчиненным ресурсом не задана или некорректно описана, то то Система передаёт соответствующее сообщение об ошибке, процесс завершается; b. иначе, связи между ресурсами заполнены корректно, переход к выполнению следующего шага. 6. Система проверяет, что перечень атрибутов, запрашиваемый Потребителем не запрещен на уровне модели данных. Для этого проверяет заполнение блока ``guard:`` в модели данных и определяет соблюдены ли условия по передачи данных атрибутов в запросе (блок ``conditions``): a. если хотя бы один атрибут запрещен для передачи Потребителю (guard заполнен в модели, а требуемый conditions не заполнен в запросе), то Система передаёт соответствующее сообщение об ошибке, процесс завершается; b. иначе, все требуемые атрибуты разрешены для передачи Потребителю, переход к выполнению следующего шага. 7. Система на основании блока ``fetch→show_events`` определяет возможность обогащения передаваемых атрибутов данными о возможных событиях (event) машины состояний. Текущий процесс завершается и вызывается исполнение плана запроса. Исполнение плана запроса ************************* .. _exe_query_plan_img: .. figure:: /_static/img/modules/smevql/exe_query_plan.png :align: center :alt: Исполнение плана запроса Исполнение плана запроса **Запускающее событие:** - Подготовлен план выполнения запроса Ход выполнения: Указанная последовательность выполняется для каждого подзапроса из плана. При этом сначала параллельно выполняются подзапросы первого уровня, затем подзапросы второго уровня на основе данных полученных на первом уровне и т.д. по всем уровням иерархии плана запроса. В качестве ответа от Источника могут быть сами запрашиваемые данные (если обращение к источнику шло в синхронном режиме) или токен (если обращение к источнику шло в асинхронном режиме). 1. Система отправляет подзапрос к источнику с указанным в плане sql-выражением. Так же на этом шаге Система обновляет счетчики лимитов в Redis, при этом количество увеличивается на величину подзапросов к источникам данных. 2. Система ожидает ответ и определяет режим обработки подзапроса к источнику ресурса. Для этого определяет значение параметра ``fetch->policy`` в модели данных ресурса: a. если установлено значение ``sync`` или ``async_on_timeout`` и ответ пришёл в течение заданного таймаута, то режим обработки подзапроса синхронный, переход к выполнению шага 2; b. иначе, установлено значение async или async_on_timeout и исчтоник не отвечает в в течение заданного таймаута, то режим обработки подзапроса асинхронный, переход к выполнению шага 6. 3. Система обрабатывает полученный ответ от источника или обрабатывает ситуацию, когда ответ не получен: a. если ответ получен и он некорректного формата или ответ не получен в заданный таймаут, то Система передаёт соответствующее сообщение об ошибке, процесс завершается; b. если, ответ корректен и получен в заданный таймаут, а источником данных является prostore, то данный процесс завершается и вызывается выполнение передачи ответа потребителю (:numref:`answer_to_consumer`); c. иначе, ответ корректен и получен в заданный таймаут, а источником данных является smevql, переход к выполнению следующего шага. 4. Система проверяет, что ответ от источника подписан цифровой подписью (далее ЦП). Для этого извлекает данные из полученного ответа (блок ``signature``) и отправляет данные ЦП на проверку в модуль Notarius. После чего дожидается результатов проверки ЦП от Notarius: a. если ЦП не прошла успешную проверку в Notarius или блок ``signature`` не заполнен источником, то ответ считается невалидным, Система передаёт соответствующее сообщение об ошибке, процесс завершается; b. иначе, ЦП прошла успешную проверку в Notarius, ответ валиден, переход к выполнению следующего шага. 5. Система накладывает свою ЦП на ответ источника. Для этого отправляет запрос в модуль Notarius и ожидает получение ответа. После чего ответ подписан ЦП (заполнен блок partials в ответе для потребителя). Процесс завершается после получения всех ответов от всех источников и вызывается выполнение передачи ответа потребителю (:numref:`answer_to_consumer`). 6. Система генерирует токен (по которому в дальнейшем Потребитель сможет отдельно запросить данные) и записывает его в блоке персистентности Redis. 7. Система в качестве временного ответа от источника подставляет токен (:numref:`get_async_data`). Процесс завершается после получения всех ответов от всех источников и вызывается выполнение передачи ответа потребителю. .. _answer_to_consumer: Передача ответа потребителю **************************** .. _answer_to_consumer_img: .. figure:: /_static/img/modules/smevql/answer_to_consumer.jpg :align: center :alt: Передача ответа потребителю Передача ответа потребителю **Запускающее событие:** - Получены все ответы от источников и/или токены. **Ход выполнения:** 1. Система формирует комплексный ответ на основе полученных ответов от источников и/или токенов. Формат ответа в таблице ниже: .. table:: Описание элементов ответа .. rst-class:: longtable +-------------------+-----------------------------------------------------------------------------------------------------------------+---------------------------------------+ | **Элемент** | **Описание** | **Пример** | +===================+=================================================================================================================+=======================================+ | response | Объект, который содержит данные запрашиваемых ресурсов и/или токенов для асинхронного получения данных ресурсов | :ref:`responce_answer_to_consumer` | | | | | +-------------------+-----------------------------------------------------------------------------------------------------------------+ :ref:`async_answer_to_consumer` | | | Название ресурса, массив данных которого был получен в источнике. | | | | | | | | Если запрос содержал подчиненные ресурсы, то данные таких ресурсов будут вставлены в массив объекта основного | | | | ресурса. | | | | | | | | Если данные ресурса должны быть получены отдельно в асинхронном режиме, то ответ будет содержать блок ``async``,| | | | который имеет следующие атрибуты: | | | | | | | | - ``token`` - токен для асинхронного обращения; | | | | | | | | - ``source`` - источник данных; | | | | - ``reason`` - тип асинхронного обращения, ``async`` - всегда асинхронное или ``async_on_timeout`` - | | | | асинхронное при превышении таймаута; | | | | | | | | - ``timeout`` - таймаут обращения к источнику; | | | | | | | | - ``request_in`` - время, по прошествии которого можно отправить повторный запрос получения данных; | | | | | | | | - ``retries_left`` - оставшееся количество попыток получения данных, если равен 0, то данные запросить | | | | невозможно. | | +-------------------+-----------------------------------------------------------------------------------------------------------------+---------------------------------------+ | credentials | Объект, содержащий общие данные запроса и информация о потребителе | :ref:`credentials_answer_to_consumer` | +-------------------+-----------------------------------------------------------------------------------------------------------------+ | | response | Объект описывает общие параметры ответа. Имеет следующие атрибуты: | | | | | | | | - ``id`` - идентификатор ответа; | | | | | | | | - ``sub_id`` - идентификатор подзапроса; | | | | | | | | - ``started_at`` - время начала формирования ответа; | | | | | | | | - ``finished_at`` - время окончания формирования ответа. | | +-------------------+-----------------------------------------------------------------------------------------------------------------+ | | system | Объект описывает параметры системы-потребителя данных. Имеет следующие атрибуты: | | | | | | | | - ``mnemonic`` - мнемоника системы; | | | | | | | | - ``instance_id`` - идентификатор экземпляра системы; | | | | | | | | - ``user_id`` - идентификатор пользователя. | | +-------------------+-----------------------------------------------------------------------------------------------------------------+ | | request | Объект описывает общие параметры запроса. Имеет следующие атрибуты: | | | | | | | | - ``id`` - идентификатор запроса; | | | | | | | | - ``sub_id`` - идентификатор подзапроса; | | | | | | | | - ``name`` - имя запроса; | | | | | | | | - ``purpose_id`` - идентификатор события, инициировавшего запрос; | | | | | | | | - ``audit`` - возможность аудита; | | | | | | | | - ``audit_id`` - идентификатор аудита. Заполняется только, если ``audit = true``. | | | | | | | | - ``audit_token`` - токен аудита. Заполняется только, если ``audit = true``. | | +-------------------+-----------------------------------------------------------------------------------------------------------------+ | | signature | Объект, содержащий данные ЦП по каждому ответу от каждого источника, а так же ЦП комплексного ответа | | +-------------------+-----------------------------------------------------------------------------------------------------------------+ | | complex | ЦП комплексного ответа, имеет следующие атрибуты: | | | | | | | | - ``digest`` - краткий обзор подписи; | | | | | | | | - ``signature`` - цифровая подпись. | | +-------------------+-----------------------------------------------------------------------------------------------------------------+ | | partials | Массив ЦП по каждому полученному ответу от источников данных. Содержит следующие атрибуты: | | | | | | | | - ``digest`` - краткий обзор подписи; | | | | | | | | - ``signature`` - цифровая подпись; | | | | | | | | - ``response_id`` - идентификатор ответа от источника; | | | | | | | | - ``jsonpath`` - название ресурса. | | +-------------------+-----------------------------------------------------------------------------------------------------------------+---------------------------------------+ .. _responce_answer_to_consumer: Пример блока ``response`` ************************** .. code-block:: json "response": { "ticket": [ { "number": 1, "price": 701.0252675821603, "trip": [ { "id": "f72f4157-e11b-4fe1-86a2-babaeb3ccd21", "duration": "07:31:03" } ] } ] } .. _async_answer_to_consumer: Пример блока ``async`` ************************* .. code-block:: json "async": { "token": "11111-22222-333333-4444-55555", "source": "region81", "reason": "async_on_timeout", "timeout": "500ms", "request_in": "10s", "retries_left": "9" } .. _credentials_answer_to_consumer: Пример блока ``credentials`` ******************************** .. code-block:: json "credentials": { "response": { "id": "fc7953cb-99ad-4a78-b49d-c3dce2c4bb89", "sub_id": "a8744e12-49ce-4524-861d-0e3b9a763d14", "started_at": "2023-02-13 07:55:23 +0300", "finished_at": "2023-02-13 07:55:23 +0300" }, "system": { "mnemonic": "117bed7f-1c07-4079-a446-1161588db4e5", "instance_id": "ccb4a88f-f44b-43e7-8a97-3e45c8345e90", "user_id": "5ed38461-0907-486a-930a-7b443482932c" }, "request": { "id": "df5a0073-c6be-4d8c-8eb2-9b2f4188a429", "sub_id": "0cdb59ce-224b-4118-8da1-c5ea08a5d955", "name": "driver_data", "purpose_id": "ed1170f1-3caa-4985-aa38-c9c5a190b770", "audit": "false", "audit_id": "fc1048fe-323d-4eeb-92df-5710b3d1d100", "audit_token": "39e47aac-45d2-44c1-8c26-2d9b28b1703b" } }, "signature": { "complex": { "digest": "985925e62ce3494a4e73f20676f1506ef64380f0", "signature": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9" }, "partials": [ { "digest": "985925e62ce3494a4e73f20676f1506ef64380f0", "signature": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9", "response_id": "fc7953cb-99ad-4a78-b49d-c3dce2c4bb89", "jsonpath": "$.response.office" } ] } } .. _get_async_data: Асинхронное получение данных клиентом """""""""""""""""""""""""""""""""""""""" Общее описание **************** Разные источники с разной скоростью передают данные и по скорости передачи данных их условно можно разделить на "быстрые" и "медленные". При взаимодействии с "быстрыми" источниками обмен клиента (потребителя) со СМЭВ QL происходит в синхронном режиме в таком случае запрашиваемые данные передаются с разу в момент обращения, а при взаимодействии с "медленными" источниками обмен происходит в асинхронном режиме, в таком случае данные передаются с определенным временным лагом. Указание типа взаимодействия, синхронное или асинхронное, определяется на уровне модели данных в блоке ``fetch->policy``. Для потребителя наличие в ответе блока ``async`` с токеном вместо данных означает, что данные необходимо получить отдельным запросом, вызвав метод ``GET/data/{token}``. Передача асинхронных данных от источника в СМЭВ QL ***************************************************** **Предварительные условия:** СМЭВ QL отправил источнику запрос получения данных (:numref:`data_request_process`) и сохранил токен. **Ход выполнения:** 1. Источник подготавливает и передает данные в асинхронном режиме. 2. СМЭВ QL записывает полученные данные в блоке персистентности в спейсе responses с временем жизни ``store_timeout``, где в качестве ключа выступает ранее сформированный токен. Пример записи асинхронных данных в блоке персистентности: - ключ (токен): ``11111-22222-333333-4444-55555`` - значение (данные от источника) .. code-block:: json {"referral": [ { "to_post_name": "врач-терапевт участковый", "end_date": null, "speciality_id": "119", "to_mo_id": "325", "mo": [ { "id": "325", "name": "ГКБ 222; Кардиология" } ] } ] } Запрос асинхронных данных потребителем ***************************************** **Предварительные условия:** - Потребитель получил ответ от СМЭВ QL с блоком async **Ход выполнения:** 1. Потребитель, спустя рекомендованное время (параметр ``async->request_in`` в ответе), отправляет запрос получения асинхронных данных. Для этого вызывает метод ``GET/data/{token}``, где в качестве ``{token}`` передаёт значение, полученное ранее в ответе (``async→token``). 2. СМЭВ QL сервер проверяет наличие данных по токену: a. если данные ещё не поступили от источника, то обновляет счётчик обращений от клиента и формирует ответ вида: .. code-block:: json { "response": {}, "asynced": { "referral": [ { "async":{ "source": "region12", "reason": "receiving_data", "timeout": "10s", "request_in": "10s", "retries_left": "5" } } ] } } b. иначе, данные были получены от источника, Система формирует ответ с данными вида: .. code-block:: json { "response": { "referral": [ { "to_post_name": "врач-терапевт участковый", "end_date": null, "speciality_id": "119", "to_mo_id": "325", "mo": [ { "id": "325", "name": "ГКБ 222; Кардиология" } ] } ] }, 3. СМЭВ QL сервер подписывает ответ ЦП с помощью Notarius и передаёт потребителю подписанный ответ. .. note:: Потребитель продолжает запрашивать данные с рекомендованным интервалом пока не получит данные или пока количество попыток ``retries_left`` не будет равно 0. .. _change_data_request: Обработка запроса изменения данных витрины через машину состояний """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" Общее описание ***************** Машина состояний СМЭВ QL сервер имеет определенное количество состояний (``states``), переход между которыми осуществляется посредством вызова событий (``events``). В зависимости типа вызываемого события выполняется разная логика по обновлению данных витрины. Основной сценарий выполнения **************************** **Запускающее событие:** Потребитель вызвал событие посредством выполнения запроса ``POST/states/{model}/{event}``. Схема процесса: .. _change_data_request_img: .. figure:: /_static/img/modules/smevql/change_data_request.png :align: center :alt: Обработка запроса изменения данных витрины через машину состояний Обработка запроса изменения данных витрины через машину состояний **Ход событий:** 1. Система проверяет тип вызываемого события: a. если событие с типом init (``POST/states/{model}/init``), то вызывается альтернативное направление (:numref:`alteranive_init`); b. иначе, событие не init, переход к выполнению следующего шага. 2. Система проверяет наличие блока ``confirm`` у вызванного события: a. если событие содержит блок ``confirm``, то вызывается альтернативное направление (:numref:`alternative_confirm`); b. иначе, событие не содержит блок confirm, переход к выполнению следующего шага. 3. Система получает данные из Prostore для ресурса, вызванной стэйт-машины и сохраняет их в оперативной памяти для последующего обращения. В качестве критерия используются: - Условия в блоке ``conditions`` исходного запроса - Значения ``attributes:`` из текущего состояния стэйт-машины Количество записей, получаемых из Prostore ограничено настройкой ``max_updated_rows`` в конфигурационном файле приложения ``application.yaml``. После получения данных, осуществляется переход к выполнению следующего шага. 4. Система проверяет в какое состояние должна перейти стэйт-машина после выполнения вызванного события. Для этого у вызванного события читается параметр ``to:`` a. если стэйт-машина должна перейти в состояние с признаком ``delete = true``, то вызывается альтернативное направление (:numref:`alternative_delete`); b. иначе, стэйт-машина должна перейти в состояние с признаком ``delete = false`` (неуказанный признак delete у события приравнивается к значению false), переход к выполнению следующего шага. 5. Система выполняет проверку наличия атрибутов, заданных в блоке ``payload`` исходного запроса, в модели данных ресурса. Атрибуты отсутствующие в модели данных ресурса игнорируются (не участвуют в последующем обновлении данных витрины). После данной проверки, осуществляется переход к выполнению следующего шага. 6. Система формирует SQL-выражение (определяет какие атрибуты должны быть обновлены) для обновления данных витрины (для выполнения операции upsert в prostore) с учетом следующих правил: - Атрибуты из ``payload`` исходного запроса применяются только, если у вызванного события признак ``updatable: true``; - Атрибуты из ``payload`` исходного запроса ограничиваются блоком ``updatable_attributes:`` (если он указан) вызванного события; - Атрибуты, полученные при выполнении ``confirm`` (:numref:`alternative_confirm`) из блока ``enrich``, применяются всегда; - Атрибуты, заданные в блоке ``attributes:`` текущего состояния стэйт-машины, применяются всегда, за исключением случая, когда у текущего состояния установлен признак ``static: true``. После формирования SQL-выражения, осуществляется переход к выполнению следующего шага. 7. Система обновляет данные ресурса в Prostore (операция upsert) значениями атрибутов, определенных на шаге 6 и только для тех записей, которые были получены на шаге 3. После обновления данных осуществляет переход к выполнению следующего шага. Опционально: если в конфигурационном файле ``application.yaml``, параметр ``state_machine_enabled: true``, то вызывает процесс передачи уведомления об изменении данных витрины. 8. Система переводит стэйт-машину в состояние, указанное в параметре to: вызванного события. После этого осуществляет переход к выполнению следующего шага. 9. Система проверят наличие блока ``hooks`` у вызванного события: a. если событие содержит блок ``hooks``, то вызывается альтернативное направление :numref:`alternative_hooks`; b. иначе, обработка события считается выполненной, завершение основного направления. .. _alteranive_init: Альтернативное направление для событий с типом init ******************************************************* Данное альтернативное направление запускается из шага 1 основного направления, когда было вызвано событие стэйт-машины с типом ``init``. Данный тип события предполагает, что в витрину данных будут добавлены новые записи. 1. Система выполняет проверку наличия атрибутов, заданных в блоке ``payload`` исходного запроса, в модели данных ресурса. Атрибуты отсутствующие в модели данных ресурса игнорируются (не участвуют в последующем обновлении данных витрины). После данной проверки, осуществляется переход к выполнению следующего шага. 2. Система формирует SQL-выражение для добавления новых записей ресурса с учетом атрибутов, отобранных на шаге 1 данного альтернативного направления. После этого переходит к выполнению следующего шага. 3. Система добавляет новые записи ресурса в Prostore (операция upsert). После этого осуществляет переход к выполнению следующего шага. 4. Система переводит стэйт-машину в состояние, у которого задан признак ``initial: true``. После чего завершается выполнение данного альтернативного и основного сценария. Опционально: если в конфигурационном файле ``application.yaml``, параметр ``state_machine_enabled: true``, то вызывает процесс передачи уведомления об изменении данных витрины (:numref:`push_state_machine_send`). .. _alternative_confirm: Альтернативное направление для событий с блоком confirm ********************************************************* Данное альтернативное направление запускается из шага 2 основного направления, когда вызванное событие имеет блок ``confirm``. Такое событие предполагает обращение к внешнему источнику с целью передачи ему и получения от него дополнительных данных. 1. Система формирует и передаёт REST-запрос внешнему источнику. Формирование запроса и определение адресата происходит на основании параметров, указанных в блоке ``confirm`` запускаемого события: ``source``, ``endpoint``, ``method``, ``body``. После этого переходит к выполнению следующего шага. 2. Система обрабатывает полученный ответ. Для этого читает условия проверки ответа, заданное в блоке ``confirm->accept`` вызванного события: a. если ответ не соответствует условиям, заданным в accept, то Система передаст соответствующую ошибку Потребителю. Завершение данного альтернативного и основного направлений. b. иначе, ответ соответствует условиям, заданным в accept или блок accept не задан, переход к выполнению следующего шага. 3. Система проверяет наличия блока ``enrich`` в описании вызванного события: a. если блок ``enrich`` отсутствует, то выполняется переход к шагу 3 основного направления. Данное альтернативное направление завершается. b. иначе, блок ``enrich`` задан, переход к выполнению следующего шага. 4. Система извлекает данные из полученного на шаге 2 ответа и сохраняет их для последующего использования. Далее выполняется переход к шагу 3 основного направления. Данное альтернативное направление завершается. .. _alternative_delete: Альтернативное направление при переходе в состояние delete ************************************************************** Данное альтернативное направление запускается из шага 4 основного направления, когда было вызвано событие после выполнения которого стэйт-машина должна перейти в состояние с признаком ``delete``. Данный тип события предполагает, что в должны быть удалены данные ресурса из витрины. 1. Система удаляет записи ресурса, полученные на шаге 3 основного направления. 2. Система переводит стэйт-машину в состояние, у которого задан признак ``delete: true.`` После чего осуществляет переход к выполнению шага 9 основного направления. Данное альтернативное направление завершается. Опционально: если в конфигурационном файле ``application.yaml``, параметр ``state_machine_enabled: true``, то вызывает процесс передачи уведомления об изменении данных витрины. .. _alternative_hooks: Альтернативное направление для событий с блоком hooks ******************************************************* Данное альтернативное направление запускается из шага 9 основного направления, когда вызванное событие имеет блок ``hooks``. Такое событие предполагает вызов другого события машины состояния, таким образом формируя вложенные вызовы событий. Количество уровней вложенных вызовов ограничено настройкой ``max_nested_event`` в конфигурационном файле приложения ``application.yaml``. Если в блоке hooks определены несколько переходов (допускается указание массива), то описанные действия выполняются для каждого перехода. 1. Система формирует REST-запрос для вызова другого события стэйт-машины по следующим правилам: - URL метода ``POST/states/{model}/{event}``: ``{model}`` - берется из параметра ``model`` блока ``hooks``; ``{event}`` - берется из параметра ``event`` блока ``hooks`` - conditions: Заполняется идентификаторами записей нового вызываемого ресурса (название ресурса соответствует названию model). Берутся записи исходного ресурса, полученные на шаге 3 основного направления, далее по связям в модели данных определяются идентификаторы записей для нового ресурса; - payload: Строится на основе payload исходного запроса, выбираются атрибуты объекта, название которого совпадает с новым вызываемым ресурсом. 2. Система передаёт REST-запрос для вызова события стэйт-машины. Переход к выполнению шага 1 основного направления, но уже с данными другого события и ресурса. Завершение данного альтернативного направления. .. _regulated_query_process: Обработка регламентированного СМЭВ QL запроса """""""""""""""""""""""""""""""""""""""""""""""""" Общее описание ******************* Для выполнения запроса к СМЭВ QL РЗ потребитель должен вызвать опубликованный метод ``POST /regulated-query``. В рамках запроса необходимо передать в теле JSON-объект заданного формата. :numref:`tab_regulated_query` содержит описание формата запроса ``POST /regulated-query``. .. _tab_regulated_query: .. table:: Обработка регламентированного СМЭВ QL запроса +--------------+---------------------------------------------------------------------+------------------------------+ | **Элемент** | **Описание** | **Пример** | +==============+=====================================================================+==============================+ | mnemonic | Мнемоника регламентированного запроса СМЭВ QL | ``"mnemonic": "test_query"`` | +--------------+---------------------------------------------------------------------+------------------------------+ | majorVersion | Мажорная версия запроса | ``"majorVersion": 1`` | +--------------+---------------------------------------------------------------------+------------------------------+ | minorVersion | Минорная версия запроса | ``"minorVersion": 0`` | +--------------+---------------------------------------------------------------------+------------------------------+ | params | Объект, содержащий значения параметров запроса в формате | .. code-block:: | | | "параметр": "значение" | | | | | "params": | | | | { | | | | "month": 1 | | | | } | +--------------+---------------------------------------------------------------------+------------------------------+ | credentials | Объект, содержащий общие данные запроса и информация о потребителе, | | | | аналогичен запросу данных (:numref:`query_post_data`) | | +--------------+---------------------------------------------------------------------+------------------------------+ Алгоритм обработки запроса ****************************** При поступлении СМЭВ QL РЗ от Потребителя СМЭВ QL сервер запускается процесс его обработки: 1. Проверка запроса и доступов: а) СМЭВ QL РЗ с такой мнемоникой и версией зарегистрирован; б) проверка мнемоники Инициатора по black_list и white_list; в) проверка параметров запроса на соответствие описанию в шаблоне; 2. Формирование запроса данных на основе СМЭВ QL РЗ и полученных параметров; 3. Исполнение запроса в соответсвии с :numref:`data_request_process`. Уведомления при изменении данных витрины (push-сервис) ########################################################## .. _push_user_register: Регистрация получателя уведомлений """""""""""""""""""""""""""""""""""""" Общее описание **************** Данная функция позволяет зарегистрировать в СМЭВ QL сервер нового получателя уведомлений при изменении данных ресурса. Помимо самого факта уведомления об изменении данных, можно получать определенные атрибуты ресурса, которые будут переданы в рамках нотификации. .. _push_user_register_img: .. figure:: /_static/img/modules/smevql/push_user_register.png :align: center :alt: Регистрация получателя уведомлений Регистрация получателя уведомлений **Предварительные условия:** - Потребитель (получатель уведомлений) вызвал запрос на регистрацию получения уведомлений ``POST/push/consumer/create`` **Ход выполнения:** 1. СМЭВ QL сервер (далее Система) проверяет входящий запрос на соответствие заданной схеме (:numref:`post_push_consumer_create`): a. если формат запроса некорректен, то Система возвращает соответствующую ошибку и завершает исполнение сценария. b. иначе, запрос корректного формата, переход к выполнению следующего шага. 2. Система проверяет к какому типу относится источник данных заданного в запросе ресурса: a. если тип источника = smevql, то Система возвращает соответствующую ошибку и завершает исполнение сценария. b. иначе, тип источника = prostore, переход к выполнению следующего шага. 3. Система сохраняет данные о получателе уведомлений в ``redis hash`` с названием ``push:consumers:[agent_target]:[resource]``, значение представляется в виде json: .. code-block:: json { "bag": ["sample_field1", "sample_field2"], "started_at": "2022-01-01 00:00:00", "finished_at": "2022-12-31 23:59:59" } 4. Система передаёт ответ с указанием ключа: .. code-block:: json { "created_consumer": { "key": "push:consumers:epgu:books" } } Завершает выполнение сценария. .. _post_push_consumer_create: Описание запроса POST/push/consumer/create ********************************************* .. table:: Описание запроса ``POST/push/consumer/create`` +-------------------+--------------------------------------------------------------------------------+ | **Элемент** | **Описание** | +===================+================================================================================+ | create_consumer | Объект, содержащий информацию о получателе уведомлений и отслеживаемом ресурсе | +-------------------+--------------------------------------------------------------------------------+ | agent | Объект, содержащий информацию об агентах СМЭВ4. Содержит следующие атрибуты: | | | | | | - ``source`` - мнемоника агента поставщика данных; | | | | | | - ``target`` - мнемоника агента получателя уведомлений. | +-------------------+--------------------------------------------------------------------------------+ | resource | Название ресурса, изменения данных которого необходимо отслеживать | +-------------------+--------------------------------------------------------------------------------+ | bag | Массив атрибутов ресурса, которые необходимо передавать получателю в момент | | | уведомления об изменении данных | +-------------------+--------------------------------------------------------------------------------+ | started_at | Время начала отслеживания изменений | +-------------------+--------------------------------------------------------------------------------+ | finished_at | Время окончания отслеживания изменений | +-------------------+--------------------------------------------------------------------------------+ Пример: .. code-block:: json { "create_consumer": { "agent": { "source": "zdrav777", "target": "epgu" }, "resource": "books", "bag": ["sample_field1", "sample_field2"], "started_at": "2022-01-01 00:00:00", "finished_at": "2022-12-31 23:59:59" } } .. _push_user_delete: Удаление получателя уведомлений """""""""""""""""""""""""""""""""""" Общее описание **************** Для того, чтобы прекратить получение уведомлений при изменении ресурса, необходимо вызвать один из следующих методов СМЭВ QL: - Удаление получателя уведомлений на конкретный ресурс: ``POST/push/consumer/delete/resource`` - Удаление получателя уведомлений на все ресурсы: ``POST/push/consumer/delete`` Сценарий выполнения ******************* .. _delete_push_user_img: .. figure:: /_static/img/modules/smevql/delete_push_user.png :align: center :alt: Удаление получателя уведомлений Удаление получателя уведомлений **Предварительные условия:** - Потребитель (получатель уведомлений) вызвал запрос на удаление получения уведомлений POST/push/consumer/delete или POST/push/consumer/delete/resource **Ход выполнения:** 1. Система проверяет входящий запрос на соответствие заданной схеме (:numref:`delete_query_descrition`): a. если формат запроса некорректен, то Система возвращает соответствующую ошибку и завершает исполнение сценария. b. иначе, запрос ``POST/push/consumer/delete/resource`` корректного формата, переход к выполнению шага 2 или запрос ``POST/push/consumer/delete`` корректного формата, переход к выполнению шага 3. 2. Система удаляет данные о получателе уведомлений на конкретный ресурс из redis: a. hash с названием ``push:consumers:[agent_target]:[resource]``; b. cсылку на hash из ``set`` c названием ``push:consumers:by:agent_target:[agent_target]``; c. ссылку на hash из ``set`` c названием ``push:consumers:by:resource:[resource]``; d. Переходит к выполнению шага 4. 3. Система удаляет данные о получателе уведомлений на все ресурсы из redis: a. получает список hash из ``set`` c названием ``push:consumers:by:agent_target:[agent_target]``, далее по всем hash: - удаляет из ``set`` ``push:consumers:by:resource:[resource]`` имя ``hash``; - удаляет ``set`` c названием ``push:consumers:by:agent:target:[agent_target]``; - удаляет hash; b. Переходит к выполнению шага 4. 4. Система передаёт ответ с указанием удаленных ключей: .. code-block:: json [ { "deleted_consumer": { "key": "push:consumers:epgu:books" } }, ... ] 5. Завершает выполнение сценария. .. _delete_query_descrition: Описание запроса ******************* .. table:: Описание запроса на удаление получателя уведомлений +-------------------+--------------------------------------------------------------------------------+ | **Элемент** | **Описание** | +===================+================================================================================+ | delete_consumer | Объект, содержащий информацию о получателе уведомлений и отслеживаемом ресурсе | +-------------------+--------------------------------------------------------------------------------+ | agent | Объект, содержащий информацию об агентах СМЭВ4. Содержит следующие атрибуты: | | | | | | - ``source`` - мнемоника агента поставщика данных; | | | | | | - ``target`` - мнемоника агента получателя уведомлений. | +-------------------+--------------------------------------------------------------------------------+ | resource | Название ресурса, при изменении данных которого должны перестать приходить | | | уведомления для заданного получателя. Заполняется только в запросе | | | ``POST/push/consumer/delete/resource`` | +-------------------+--------------------------------------------------------------------------------+ Пример: .. code-block:: json { "delete_consumer": { "agent": { "source": "zdrav777", "target": "epgu" }, "resource": "books" } } .. _push_user_list_request: Запрос списка получателей уведомлений """""""""""""""""""""""""""""""""""""""" Общее описание ***************** Для того, чтобы запросить список получателей уведомлений, необходимо вызвать один из следующих методов СМЭВ QL: - Получатели уведомлений конкретного ресурса: ``GET/push/consumer/agent_targets/{resource}``; - Все получатели уведомлений данного СМЭВ QL: ``GET/push/consumer``. Сценарий выполнения ********************** .. _push_user_list_request_img: .. figure:: /_static/img/modules/smevql/push_user_list_request.png :align: center :alt: Запрос списка получателей уведомлений Запрос списка получателей уведомлений **Предварительные условия:** - Клиент вызвал запрос списка получателей уведомлений ``GET/push/consumer`` или ``GET/push/consumer/agent_targets/{resource}``. **Ход выполнения:** 1. Система выполняет поиск данных о получателях уведомлений в redis. При этом, если был вызван метод ``GET/push/consumer``, то Система получает все имена ``hash`` из ``set push:consumers`` и значения всех ``hash``, а если был вызван метод ``GET/push/consumer/agent_targets/{resource}``, то Система получает имена ``hash`` из ``set push:consumers:by:resource:[resource]`` и значения ``hash`` в рамках указанного ресурса. a. если данные не были найдены, то Система возвращает соответствующую ошибку и завершает исполнение сценария. b. иначе, данные были найдены, переход к выполнению следующего шага. 2. Система формирует и передаёт ответ клиенту с указанием: a. перечня всех получателей уведомлений, если был вызван метод ``GET/push/consumer``. b. перечня получателей уведомлений при изменении конкретного ресурса, если был вызван метод ``GET/push/consumer/agent_targets/{resource}``. Формат ответа не меняется в зависимости от вызванного метода, отличается только количество передаваемых данных. Пример ответа: .. code-block:: json [ { "agent": { "target": "epgu" }, "key": "push:consumers:epgu:books" "resource": "books", "bag": ["sample_field1", "sample_field2"], "started_at": "2022-01-01 00:00:00", "finished_at": "2022-12-31 23:59:59" }, ... ] .. _listen_data_request: Запрос данных об отслеживаемых ресурсах """""""""""""""""""""""""""""""""""""""" Общее описание **************** Данная функция позволяет получить перечень отслеживаемых ресурсов заданным потребителем. Для этого клиенту необходимо вызвать метод ``GET/push/consumer/resources/{agent_target}``, где в качестве ``{agent_target}`` передать значение мнемоники Агента Потребителя. Сценарий выполнения ********************** .. _listen_data_request_img: .. figure:: /_static/img/modules/smevql/listen_data_request.png :align: center :alt: Запрос данных об отслеживаемых ресурсах Запрос данных об отслеживаемых ресурсах **Предварительные условия:** - Клиент вызвал запрос списка отслеживаемых ресурсов ``GET/push/consumer/resources/{agent_target}``. **Ход событий:** 1. Система выполняет поиск данных об отслеживаемых ресурсах в redis: получает имена ``hash`` из ``set`` ``push:consumers:by:agent_target:[agent_target]`` и значения ``hash``. a. если данные не были найдены, то Система возвращает соответствующую ошибку и завершает исполнение сценария. b. иначе, данные были найдены, переход к выполнению следующего шага. 2. Система формирует и передаёт ответ клиенту. Завершает выполнение сценария. Пример ответа: .. code-block:: json [ { "agent": { "target": "epgu" }, "key": "push:consumers:epgu:books" "resource": "books", "bag": ["sample_field1", "sample_field2"], "started_at": "2022-01-01 00:00:00", "finished_at": "2022-12-31 23:59:59" }, ... ] .. _push_state_machine_send: Передача уведомления при вызове события машины-состояний """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""" Общее описание ***************** Передача уведомлений об изменении данных витрины средствами СМЭВ QL сервер возможна при выполнении определенного перехода машины состояний (:numref:`change_data_request`). Формирование и передача уведомления происходит в следующих случаях: - Добавление новой записи в Prostore (для событий с типом ``init``); - Удаление данных в Prostore (при переходе в состояние с типом ``delete``); - Обновление данных в Prostore. Сценарий выполнения ******************** .. _push_state_machine_send_img: .. figure:: /_static/img/modules/smevql/push_state_machine_send.png :align: center :alt: Передача уведомления при вызове события машины-состояний Передача уведомления при вызове события машины-состояний **Предварительные условия:** - Стэйт машина передала перечень измененных (новые, обновлённые, удалённые) записей ресурсов; - Получатель зарегистрировал REST-метод (``POST/api/v1/smevql/notify``) для приёма уведомлений. **Ход событий:** Данные шаги выполняются в цикле для каждой записи измененного ресурса. 1. Система проверяет есть ли зарегистрированные получатели уведомлений при изменении заданного ресурса. Для этого читает из redis ``set`` c названием ``push:consumers:by:resource`` ссылки на зарегистрированных получателей, для каждой ссылки: читает из redis hash данные получателя; проверяет активность получателя на текущий момент. a. если не найдено ни одного активного получателя, то передача уведомления не требуется, завершение сценария для данной записи измененного ресурса. b. иначе, найден один или более активных получателей, переход к выполнению следующего шага. 2. Система формирует сообщение (содержимое уведомления) для каждого получателя, определенного на шаге 1 (:numref:`push_format_description`). При необходимости (если при регистрации получения уведомлений (:numref:`push_user_register`) был заполнен раздел **bag**) получает дополнительные атрибуты измененного ресурса из витрины. Далее переходит к выполнению следующего шага. 3. Система отправляет уведомления параллельно каждому получателю (отправка уведомления выполняется методом post на адрес агента) и дожидается ответа: a. если ответа не поступило в течение заданного таймаута или в ответе получена ошибка (400-500), то Система фиксирует попытку отправки (накопление счётчика) и переходит к выполнению следующего шага. b. иначе, уведомление было успешно отправлено получателю, завершение сценария для данной записи измененного ресурса. 4. Система определяет требуется ли выполнить повторную отправку уведомления. Для этого сравнивает текущее значение счётчика попыток отправки уведомления с параметром, заданным в конфигурационном файле ``application.yaml`` ``push->retry->max_attempts``: a. если максимальное количество попыток отправки уведомления превышено, то повторная отправка не требуется, Система сохраняет соответствующее сообщение об ошибке в лог, завершение сценария для данной записи измененного ресурса. b. иначе, требуется повторная попытка отправки уведомления, Система возвращается к выполнению шага 3. .. _push_format_description: Описание формата уведомления ******************************* .. table:: Описание формата уведомления +-------------------+--------------------------------------------------------------------------------+ | **Элемент** | **Описание** | +===================+================================================================================+ | agent | Объект, содержащий информацию об агентах СМЭВ4 | +-------------------+--------------------------------------------------------------------------------+ | source | мнемоника агента поставщика данных | +-------------------+--------------------------------------------------------------------------------+ | target | мнемоника агента получателя уведомлений | +-------------------+--------------------------------------------------------------------------------+ | payload | Сутевые данные уведомления | +-------------------+--------------------------------------------------------------------------------+ | type | Тип уведомления. | | | | | | Заполняется значение ``entity``, это | | | означает, что уведомление инициировано событием стэйт машины | +-------------------+--------------------------------------------------------------------------------+ | source | Мнемоника источника данных измененного ресурса | +-------------------+--------------------------------------------------------------------------------+ | entity | Данные, полученные из стэйт машины. Содержит следующие атрибуты: | | | | | | - ``resource`` - название измененного ресурса; | | | | | | - ``entity_id`` - идентификатор записи измененного ресурса; | | | | | | - ``state`` - состояние стэйт машины; | | | | | | - ``updated_at`` - время изменения записи ресурса; | | | | | | - ``bag`` - перечень атрибутов измененного ресурса со значениями. | +-------------------+--------------------------------------------------------------------------------+ | push_id | Идентификатор уведомления | +-------------------+--------------------------------------------------------------------------------+ Пример: .. code-block:: json { "notification": { "agent": { "source": "zdrav777", "target": "epgu" }, "payload": { "type": entity "source": "prostore", "entity": { "resource": "books", "entity_id": 25, "state": "received", "updated_at": "2023-11-23 12:25:31", "bag": { "sample_field1": "sample_value" } } }, "push_id": "UUID" } } .. _push_method_user_side: Регистрация метода для получения уведомлений на стороне клиента """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" Для того, чтобы потребитель имел возможность получать уведомления об изменении данных витрины, ему необходимо: 1. Развернуть на своей стороне REST-сервис, в котором реализовать метод ``POST/api/v1/smevql/notify``; 2. Настроить REST-сервис для взаимодействия с Агентом СМЭВ4 Потребителя; 3. Зарегистрировать REST-сервис в СМЭВ4; 4. Добавить критерии доступа (права поставщику данных) для запросов к развернутому REST-сервису; 5. Выполнить процедуру регистрации получения уведомлений в СМЭВ QL. .. table:: Спецификация запроса +-------------------+--------------------------------------------------------------------------------+ | **Элемент** | **Описание** | +===================+================================================================================+ | agent | Объект, содержащий информацию об агентах СМЭВ4 | +-------------------+--------------------------------------------------------------------------------+ | source | мнемоника агента поставщика данных | +-------------------+--------------------------------------------------------------------------------+ | target | мнемоника агента получателя уведомлений | +-------------------+--------------------------------------------------------------------------------+ | payload | Сутевые данные уведомления | +-------------------+--------------------------------------------------------------------------------+ | type | Тип уведомления. | | | | | | На текущий момент всегда заполняется значение ``entity``, это | | | означает, что уведомление инициировано событием стэйт машины | +-------------------+--------------------------------------------------------------------------------+ | source | Мнемоника источника данных измененного ресурса | +-------------------+--------------------------------------------------------------------------------+ | entity | Данные, полученные из стэйт машины. Содержит следующие атрибуты: | | | | | | - ``resource`` - название измененного ресурса; | | | | | | - ``entity_id`` - идентификатор записи измененного ресурса; | | | | | | - ``state`` - состояние стэйт машины; | | | | | | - ``updated_at`` - время изменения записи ресурса; | | | | | | - ``bag`` - перечень атрибутов измененного ресурса со значениями. | +-------------------+--------------------------------------------------------------------------------+ | push_id | Идентификатор уведомления | +-------------------+--------------------------------------------------------------------------------+ Приммер: .. code-block:: json { "notification": { "agent": { "source": "zdrav777", "target": "epgu" }, "payload": { "type": entity "source": "prostore", "entity": { "resource": "books", "entity_id": 25, "state": "received", "updated_at": "2023-11-23 12:25:31", "bag": { "sample_field1": "sample_value" } } }, "push_id": "UUID" } } .. _prostore_based_push: Передача уведомления на основе сообщения топика Prostore """""""""""""""""""""""""""""""""""""""""""""""""""""""""""" Общее описание ***************** При изменении данных витрины, Prostore формирует событие типа ``WRITE_OK`` и передаёт его в системный топик ``status.event``. Примеры сообщений системного топика: .. code-block:: json //пример сообщения для версионированной таблицы key: {"datamart":"foo","datetime":"2024-02-05 09:52:40.65","event":"WRITE_OK","eventLogId":"f5706095-9dc9-445f-bc93-11683676e3b3"} value: {"entity":"cat","cn":1,"ts":1707126760643000,"rowsAffected":1} //пример сообщения для не версионированной таблицы key: {"datamart":"foo","datetime":"2024-02-05 14:34:23.119","event":"WRITE_OK","eventLogId":"ebb8d74c-d0c2-4f2c-9177-872d1bcb64c6"} value: {"entity":"catp","cn":null,"ts":null,"rowsAffected":1} Данная функция позволяет передать уведомление об изменении данных витрины на основе событий системного топика Prostore. Сценарий выполнения ********************** .. _prostore_based_push_img: .. figure:: /_static/img/modules/smevql/prostore_based_push.png :align: center :alt: Схема передачи уведомления на основе сообщения топика Prostore Схема передачи уведомления на основе сообщения топика Prostore **Предварительные условия:** - Получатель зарегистрировал REST-метод ``POST/api/v1/smevql/notify`` для приёма уведомлений; - В топике ``status.event`` появилось сообщение типа ``WRITE_OK``. **Ход событий:** 1. СМЭВ QL (далее Система) проверяет изменение данных выполнено в таблице вида standalone: a. если да, то переходит к выполнению следующего шага b. иначе, изменения не в ``standalone`` таблице, переход к выполнению шага 3. 2. Система определяет ``readable`` название ``standalone-таблицы``. Для этого берет, полученное в сообщении название ``writable``, и ищет соответствующее ему readable название в блоке ``standalone-tables`` конфигурационного файла ``application.yaml``. Далее переходит к выполнению следующего шага. 3. Далее Система выполняет поиск ресурса, к которому относится измененная таблица, на основе загруженных моделей данных: a. если ресурс не найден, то Система сохраняет соответствующее сообщение в лог и завершает выполнение сценария. b. иначе, ресурс определен, переход к выполнению следующего шага. 4. Система проверяет есть ли зарегистрированные получатели уведомлений при изменении заданного ресурса. Для этого читает из redis **set** c названием ``push:consumers:by:resource`` ссылки на зарегистрированных получателей, для каждой ссылки: читает из redis **hash** данные получателя; проверяет активность получателя на текущий момент. a. если не найдено ни одного активного получателя, то передача уведомления не требуется, завершение сценария для данной записи измененного ресурса. b. иначе, найден один или более активных получателей, переход к выполнению следующего шага. 5. Затем формирует запрос к Prostore для получения данных о существовании и типе изменённой таблицы. После чего переходит к выполнению следующего шага. 6. Система получает ответ с информацией об измененной таблице: a. если таблица не существует в Prostore, то Система сохраняет соответствующее сообщение в лог и завершает выполнение сценария. b. иначе, таблица существует в Prostore, переход к выполнению следующего шага. 7. Система обрабатывает значение полученного типа таблицы: a. если таблица нетемпоральная (включая proxy-таблицы) , то переход к выполнению следующего шага. b. иначе, таблица темпоральная, переход к выполнению шага 9. 8. Система формирует sql-запрос к Prostore для получения даты последнего изменения (**anchor**) и даты удаления (**soft-delete**) записи. После чего переходит к выполнению следующего шага. 9. Система формирует сообщение (содержимое уведомления) для каждого получателя, определенного на шаге 4 (формат уведомления см. :numref:`tab_push_format_description`). При этом если при регистрации получения уведомлений был заполнен раздел **bag**, то он не формируется. Далее переходит к выполнению следующего шага. 10. Система отправляет уведомления параллельно каждому получателю (отправка уведомления выполняется методом ``POST/api/v1/smevql/notify`` на адрес агента) и дожидается ответа: a. если ответа не поступило в течение заданного таймаута или в ответе получена ошибка (400-500), то Система фиксирует попытку отправки (накопление счётчика) и переходит к выполнению следующего шага. b. иначе, уведомление было успешно отправлено получателю, завершение сценария для данной записи измененного ресурса. 11. Система определяет требуется ли выполнить повторную отправку уведомления. Для этого сравнивает текущее значение счётчика попыток отправки уведомления с параметром, заданным в конфигурационном файле ``application.yaml`` ``push->retry->max_attempts``: a. если максимальное количество попыток отправки уведомления превышено, то повторная отправка не требуется, Система сохраняет соответствующее сообщение об ошибке в лог, завершение сценария для данной записи измененного ресурса. b. иначе, требуется повторная попытка отправки уведомления, Система возвращается к выполнению шага 10. .. _tab_push_format_description: .. table:: Описание формата уведомления +------------+-----------------------------------------------------------------------------------------+ | Элемент | Описание | +============+=========================================================================================+ | agent | Объект, содержащий информацию об агентах СМЭВ4 | +------------+-----------------------------------------------------------------------------------------+ | source | мнемоника агента поставщика данных | +------------+-----------------------------------------------------------------------------------------+ | target | мнемоника агента получателя уведомлений | +------------+-----------------------------------------------------------------------------------------+ | payload | Сутевые данные уведомления | +------------+-----------------------------------------------------------------------------------------+ | type | Тип уведомления. | | | | | | Заполняется значение **batch**, это означает, что уведомление инициировано событием | | | системного топика Prostore | +------------+-----------------------------------------------------------------------------------------+ | source | немоника источника данных измененного ресурса | +------------+-----------------------------------------------------------------------------------------+ | batch | Данные, полученные из сообщения системного топика Prostore. | | | | | | Содержит следующие атрибуты: | | | | | | - ``resource`` - название измененного ресурса | | | | | | - ``updated_at`` - время изменения события | | | | | | - ``sys_cn`` - номер изменения | | | | | | - ``anchor`` - время изменения записи в БД. Для темпоральных таблиц всегда ``null`` | | | | | | - ``soft-delete`` - время удаления записи в БД. Для темпоральных таблиц всегда ``null`` | +------------+-----------------------------------------------------------------------------------------+ | push_id | Идентификатор уведомления | +------------+-----------------------------------------------------------------------------------------+ Пример: .. code-block:: json { "notification": { "agent": { "source": "zdrav777", "target": "epgu" }, "payload": { "type": batch "source": "prostor", "batch": { "resource": "books", "updated_at": "2023-11-23 12:25:31", "sys_cn": 134, "anchor": null, "soft-delete": null } }, "push_id": "UUID" } } .. _regulated_query_description: Работа с Регламентированными СМЭВ QL запросами ############################################### Создание СМЭВ QL РЗ """"""""""""""""""""" Для создания СМЭВ QL РЗ необходимо создать директорию соответствующую мнемонике запроса в директории ``queries`` в файловой системе СМЭВ QL сервера. Мнемоники СМЭВ QL РЗ являются регистронезависимыми. В случае обнаружения дублирующих запросов при загрузке или валидации СМЭВ QL сервер возвращает ``warning`` с сообщением о дублировании РЗ. В случае дублирования должен использоваться первый найденный РЗ, а другие игнорироваться. В данной директории должны содержаться поддерриктории версий СМЭВ QL РЗ, в каждой из которых расположен файл шаблона запроса ``query.json``. .. _img_queries: .. figure:: /_static/img/modules/smevql/img_queries.png :align: center :alt: Файловая система queries Файловая система queries Формат описания шаблона запроса *********************************** Шаблон запроса описывается в формате JSON и состоит из двух блоков: ``query`` и ``params``. **Требовния к блоку запроса (query):** 1. Блок должен соответствовать схеме для стандартного запроса данных, за исключением наличия мест для подстановки параметров; 2. Подстановка параметра в блок запроса (query) выполняется с использование двоеточия перед мнемоникой параметра (":month" из примера); 3. Не должен содержать параметры не описанные в блоке параметров; 4. Должен содержать все параметры, описанные в блоке параметров. **Требовния к блоку параметров (params):** 1. Данный блок является опциональным (допустимо создание запросов без параметров); 2. Должен содержать массив параметров, для каждого из которых указывается: а) Мнемоника (должна быть уникальна для данного РЗ, регистронезависимая); б) Описание; в) Тип параметра необходимо выбирать из JSON типов: i) STRING ii) NUMBER iii) INTEGER iv) BOOLEAN v) ARRAY vi) OBJECT Другие блоки, кроме query и params в шаблоне запрещены. Пример определения СМЭВ QL РЗ: .. code-block:: json { // аналогично блоку query в запросе к СМЭВ QL серверу POST /data "query": { "ticket": { "conditions": { // подстановка параметров "month": ":month" }, "attributes": ["id", "price"] } }, // блок описания параметров "params": [{ "mnemonic": "month", "descripton": "Месяц за который необходимо выгрузить статистику", "type": "INTEGER" } ] } Создание новой версии СМЭВ QL РЗ """""""""""""""""""""""""""""""""""" Добавление новых версий СМЭВ QL РЗ производится Администратором сервиса в ручную. Для этого необходимо в директории соответствующей мнемонике запроса создать новую поддиректорию с номером версии и новым файлом ``query.json``. При добавлении версии СМЭВ QL РЗ не требуется какое-либо изменение модели данных СМЭВ QL. Проверка валидности СМЭВ QL РЗ """""""""""""""""""""""""""""""" Функция валидации СМЭВ QL РЗ вызывается вручную Администратором сервиса из консоли, командой: .. code-block:: bash ./smevql test query .. .. ... | all При этом проверяется - список СМЭВ QL РЗ ``.. .. ...``; - все СМЭВ QL РЗ, при выборе опции ``all``. Каждый из РЗ проверяется на соответствие формату описания, а также на наличие дублей.