3. Использование ПОДД СМЭВ
3.1. SQL-синтаксис
Регламентированные SQL-запросы, регистрируемые в ПОДД СМЭВ должны соответствовать следующему синтаксису.
№ |
Описание |
Пример запроса |
|---|---|---|
Числовые типы данных |
||
1 |
Типы данных INTEGER и SMALLINT |
|
2 |
Типы данных REAL, DOUBLE PRECISION и FLOAT |
|
3 |
Типы данных DECIMAL и NUMERIC |
|
4 |
Арифметические операторы |
|
5 |
Числовые сравнения |
|
6 |
Неявные преобразования между числовыми типами данных |
|
Символьные типы данных |
||
7 |
Тип данных CHARACTER Длина по умолчанию 30 |
|
8 |
Тип данных CHARACTER VARYING Длина по умолчанию 30 |
|
9 |
Символьные строки |
|
10 |
Функция CHARACTER_LENGTH убирает завершающие пробелы из значений CHARACTER перед подсчётом символов |
|
11 |
Функция OCTET_LENGTH |
|
12 |
Функция SUBSTRING |
|
13 |
Конкатенация символьных строк |
|
14 |
Функции UPPER и LOWER |
|
15 |
Функция TRIM |
|
16 |
Неявные преобразования между типами символьных строк |
|
17 |
Функция POSITION |
|
18 |
Сравнения символов |
|
Идентификаторы |
||
19 |
Идентификаторы с разделителями |
|
20 |
Идентификаторы в нижнем регистре |
|
21 |
Завершающее подчёркивание |
|
Базовое определение запросов |
||
22 |
SELECT DISTINCT |
|
23 |
Предложение GROUP BY |
|
24 |
GROUP BY может содержать колонки не из <списка выборки> |
|
25 |
Элементы списка выборки могут переименовываться |
|
26 |
Предложение HAVING |
|
27 |
Корреляционные имена в предложении FROM |
|
28 |
Переименование колонок в предложении FROM |
|
Базовые предикаты и условия поиска |
||
29 |
Предикат сравнения |
|
30 |
Предикат BETWEEN |
|
31 |
Предикат IN со списком значений |
|
32 |
Предикат LIKE |
|
33 |
Предложение ESCAPE в предикате LIKE |
|
34 |
Предикат NULL |
|
35 |
Предикаты количественного сравнения |
|
36 |
Предикат EXISTS |
|
37 |
Подзапросы в предикате сравнения |
|
38 |
Подзапросы в предикате IN |
|
39 |
Подзапросы в предикате количественного сравнения |
|
40 |
Коррелирующие подзапросы |
|
41 |
Условие поиска |
|
Простые выражения с запросами |
||
42 |
Табличный оператор UNION DISTINCT |
|
43 |
Табличный оператор UNION ALL |
|
44 |
Табличный оператор EXCEPT DISTINCT |
|
45 |
Колонки, объединяемые табличными операторами, могут иметь разные типы данных |
|
46 |
Табличные операторы в подзапросах |
|
Функции множеств |
||
47 |
AVG |
|
48 |
COUNT |
|
49 |
MAX |
|
50 |
MIN |
|
51 |
SUM |
|
52 |
Дополнение ALL |
|
53 |
Дополнение DISTINCT |
|
54 |
Оператор SELECT, возвращающий одну строку |
|
Базовая поддержка курсоров |
||
55 |
Колонки ORDER BY, отсутствующие в списке выборки |
|
56 |
Выражения значений в предложении ORDER BY |
|
57 |
Поддержка NULL (NULL вместо значений) |
|
Базовое соединение таблиц |
||
58 |
Внутреннее соединение (но не обязательно с ключевым словом INNER) |
|
59 |
Ключевое слово INNER |
|
60 |
LEFT OUTER JOIN |
|
61 |
RIGHT OUTER JOIN |
|
62 |
Внешние соединения могут быть вложенными |
|
63 |
Внутренняя таблица с левой или правой стороны внешнего соединения может также участвовать во внутреннем соединении |
|
64 |
Поддерживаются все операторы сравнения (а не только =) |
|
Базовая поддержка даты и времени |
||
65 |
Тип данных DATE (включая поддержку строк DATE) |
|
66 |
Тип данных TIME (включая поддержку строк TIME) с точностью до секунд как минимум с 0 знаков после запятой |
|
67 |
Тип данных TIMESTAMP (включая поддержку строк TIMESTAMP) с точностью до секунд как минимум с 0 и 6 знаками после запятой |
|
68 |
Предикаты сравнения с типами данных DATE, TIME и TIMESTAMP |
|
69 |
Явное приведение (CAST) между типами даты/времени и типами символьных строк |
|
70 |
CURRENT_DATE |
|
71 |
LOCALTIME |
|
72 |
LOCALTIMESTAMP |
|
Расширенная поддержка даты и времени |
||
73 |
FOR SYSTEM_TIME (запрос данных, актуальных на указанную дату и время) |
|
74 |
Указание «TIMESTAMP» опционально Вычисление интервала (c указанием единиц времени: YEAR, MONTH, DAY, HOUR, MINUTE, SECOND) |
|
75 |
Функция CAST |
|
Выражение CASE |
||
76 |
Простой оператор CASE |
|
77 |
Оператор CASE с условиями |
|
78 |
NULLIF |
|
79 |
COALESCE |
|
80 |
Длинные идентификаторы |
|
81 |
Спецсимволы Unicode в идентификаторах |
|
82 |
Спецсимволы Unicode в текстовых строках |
|
83 |
Национальные символы |
|
84 |
Скалярные значения подзапросов |
|
85 |
Расширенный предикат NULL |
|
3.2. Примеры запросов с использованием SQL-синтаксиса, поддерживаемого ПОДД СМЭВ
Далее приведены примеры SQL-выражений Регламентированных SQL-запросов.
Необходимо учитывать, что возможность выполнения соответствующих синтаксических конструкций зависит от их поддержки со стороны ПО Витрины данных.
3.2.1. Запрос с использованием табличных выражений
with cte as (
select shortname, regioncode, oktmo from fias.addrobj
where formalname = ‘Москва’
)
select * from cte
Запросы с использованием базовых операторов
Запрос с использованием EXCEPT:
select oktmo from fias.addrobj
EXCEPT
select kod2 from oktmo.oktmo
Запрос с использованием INTERSECT:
select oktmo from fias.addrobj
INTERSECT
select kod2 from oktmo.oktmo
Запросы с использованием UNION:
select oktmo from fias.addrobj
UNION
select kod2 from oktmo.oktmo
Запросы с использованием ORDER BY:
select shortname, formalname from fias.addrobj
where aolevel = 1
order by formalname
select shortname, formalname from fias.addrobj
where aolevel = 1
order by formalname desc
Запрос использованием GROUP BY, HAVING:
select ao.regioncode, count(*) N from fias.addrobj ao
left join oktmo.oktmo o on o.kod2 = ao.oktmo
where o.kod2 is null
group by ao.regioncode
having COUNT(*) > 3000
order by N desc
3.2.2. Указание в запросе версии Витрины
select * from egrul.1.0.legalentity
select * from egrul.2.0.legalentity
Результат может содержать разное количество возвращаемых атрибутов в соответствии со структурой таблицы «legalentity» Витрины «egrul» версий 1.0 и 2.0.
3.2.3. Запросы с использованием JOIN
select le.short_name, rc.region_full_name from egrul.legalentity le
join egrul.region_codes rc on le.region_code = rc.region_code
SELECT ao.oktmo, o.name, o.kod
from fias.addrobj ao
JOIN oktmo.oktmo o on ao.oktmo = o.kod2
WHERE ao.offname = ‘Москва’ AND o.regionname = ‘город Москва’
select le.short_name, le.region_code, o.regionid, o.name, o.regionname from egrul.legalentity le
left join oktmo.oktmo o on cast(o.regionid as varchar) = le.region_code
where o.kod2 is null
select le.short_name, le.region_code, o.regionid, o.name, o.regionname from egrul.legalentity le
full join oktmo.oktmo o on cast(o.regionid as varchar) = le.region_code
where le.ogrn is null or o.kod2 is null
select le.short_name, le.region_code, o.regionid, o.name, o.regionname from egrul.legalentity le
right join oktmo.oktmo o on cast(o.regionid as varchar) = le.region_code
where le.ogrn is null
select le.short_name, rc.region_full_name from egrul.legalentity le
cross join egrul.region_codes rc
where rc.region_code = le.region_code
3.3. Выполнение регламентированных SQL-запросов
3.3.1. Правила выполнения
Вызов Регламентированного SQL-запроса может быть выполнен с использованием:
REST-интерфейса в соответствии с Раздел 2.3.1.
JDBC-интерфейса в соответствии с Раздел 2.3.3.
Возможность указания надстроек при вызове регламентированного SQL-запроса ограничена и в будущем будет отключена. Поэтому рекомендуется сразу использовать методы упрощенного вызова:
через REST-интерфейс в соответствии c Раздел 2.3.1.1.1;
через JDBC-интерфейс:
CALL <мнемоника Витрины>.<версия Регламентированного SQL-запроса>.<мнемоника Регламентированного SQL-запроса>(<параметры>)
Методы чувствительны к регистру, необходимо использовать нижний регистр.
При необходимости использования методов с возможностью использования надстроек необходимо составить SQL выражение, указав мнемонику Регламентированного SQL-запроса вместо таблицы. Формат Регламентированного SQL-запроса имеет вид:
select * from <мнемоника Витрины>.<версия Регламентированного SQL-запроса>.<мнемоника Регламентированного SQL-запроса>(<параметры>) <надстройки (опционально)>
где:
<мнемоника Витрины> – для простых запросов (к одной Витрине) задается мнемоника соответствующей Витрины. Для распределенного запроса вместо мнемоники Витрины указывается префикс «podd»;
<версия Регламентированного SQL-запроса> – задается в формате «major.minor»;
<мнемоника Регламентированного SQL-запроса> – мнемоника вызываемого Регламентированного SQL-запроса;
<параметры> – указываются в скобках через запятую для Регламентированного SQL-запроса с параметрами, заданными в определении.
Если выполняемый запрос не требует указания параметров, то скобки должны быть указаны пустыми. Если параметры не указаны в исходном запросе, но их значения по умолчанию присутствуют в загруженном определении, то они будут подставлены автоматически.
<надстройки (опционально)> – дополнительные условия фильтрации и операций над получаемыми данными ()например, order by, limit, where и т.д.)
Внимание
если запрос не является аналитическим и необходимо получение результата выполнения в реальном времени (запросы граждан на портале ЕПГУ, предоставление услуг в МФЦ и т.п.), то обязательно указание лимита (limit) с минимально возможным значением (максимально допустимое значение зависит от конфигурации и настроек Витрины Поставщика, по умолчанию равно 1000):
POST «https://<host>:<port>/query?async=false»
Accept-Version:1
Content-Type:application/x-www-form-urlencoded; encoding=utf-8
priority:NORMAL
timeout:60
sql: select * from fias.1.0.addrobj_view('001') limit 10
Правила указания параметров:
Если параметры заданы в SQL-выражении Регламентированного SQL-запроса в виде «?», то при вызове они должны быть указаны в порядке, соответствующем определению Регламентированного SQL-запроса. Количество параметров при вызове должно соответствовать количеству параметров в определении Регламентированного SQL-запроса.
Для запроса, в SQL-выражении которого параметры заданы как именованные, доступен:
Вызов с использованием мнемоники именованного параметра.
Для этого необходимо задать значения всех именованных параметров, для которых не задано значение по умолчанию, в виде «<мнемоника параметра>=><значение параметра>» (Раздел 3.3.2).
Мнемоника именованного параметра при вызове запроса должна соответствовать мнемонике именованного параметра в определении Регламентированного SQL-запроса.
Использование именованных параметров позволяет при вызове задавать значения параметров в любом порядке и только один раз, независимо от количества мест, где этот параметр используется в определении Регламентированного SQL-запроса.
Вызов без использования мнемоники именованного параметра.
Для этого необходимо задать значения всех именованных параметров в порядке, соответствующем определению Регламентированного SQL-запроса.
Совместное использование именованных и неименованных параметров не допускается.
3.3.2. Примеры вызова и преобразования исходного запроса
Регламентированный SQL-запрос с параметрами без имени:
// Исходный запрос от Потребителя данных ПОДД СМЭВ:
select * from oktmo.1.0.oktmo_view(‘Московская область’,7)
// Определение Регламентированного SQL-запроса
select id, whenadd, name, regionname, settlementtypename FROM oktmo.1.0.oktmo where regionname = ? AND settlementtypeid = ?
// Пример преобразования исходного запроса в соответствии с загруженным определением Регламентированного SQL-запроса:
select id, whenadd, name, regionname, settlementtypename FROM oktmo.1.0.oktmo where regionname = ‘Московская область’ AND settlementtypeid = 7
Регламентированный SQL-запрос с именованными параметрами:
// Исходный запрос от Потребителя данных ПОДД СМЭВ (вызов через мнемонику параметра)
select * from <мнемоника Витрины>.<версия Регламентированного SQL-запроса>.<мнемоника Регламентированного SQL-запроса>(param=>'000', lim=>20)
// Исходный запрос от Потребителя данных ПОДД СМЭВ
select * from <мнемоника Витрины>.<версия Регламентированного SQL-запроса>.<мнемоника Регламентированного SQL-запроса>('000',20)
// Определение Регламентированного SQL-запроса
SELECT name, code FROM datamart.1.0.regions WHERE code=:param and id in (select id from :param) limit :lim
// Пример преобразования исходного запроса в соответствии с загруженным определением Регламентированного SQL-запроса:
SELECT name, code FROM datamart.1.0.regions WHERE code='000' and id in (select id from '000') limit 20
Регламентированный SQL-запрос с параметром типа TIMESTAMP:
// Исходный запрос от Потребителя данных ПОДД СМЭВ при подключении к Pulsar
select * from fias.1.0.addrobj_view('001', '000', TIMESTAMP '1970-01-01 00:00:00')
// Исходный запрос от Потребителя данных ПОДД СМЭВ при подключении к брокеру
CALL fias.1.0.addrobj_view('001', '000', TIMESTAMP '1970-01-01 00:00:00')
// Исходный запрос от Потребителя данных ПОДД СМЭВ при подключении к брокеру с отдельным блоком параметров
datamart: fias
mnemonic: addrobj_view
majorVersion: 1
minorVersion: 0
params:{ “type”: “STRING”, “value”:”001”},{ “type”: “STRING”, “value”:“002”},{ “type”: “TIMESTAMP”, “value”:“2007-12-03Т10:00:00.000Z”}
// Определение РЗ
SELECT oktmo, formalname, startdate, enddate FROM datamart.9.1.addrobj WHERE areacode=? and citycode=? and startdate<=?
Регламентированный SQL-запрос с параметром типа DATE:
// Исходный запрос от Потребителя данных ПОДД СМЭВ при подключении к Pulsar
select * from fias.1.0.addrobj_view('001', '000', '1970-01-01')
// Исходный запрос от Потребителя данных ПОДД СМЭВ при подключении к брокеру
CALL fias.1.0.addrobj_view('001', '000', '1970-01-01')
// Исходный запрос от Потребителя данных ПОДД СМЭВ при подключении к брокеру с отдельным блоком параметров
datamart: fias
mnemonic: addrobj_view
majorVersion: 1
minorVersion: 0
params:{ “type”: “STRING”, “value”:”001”},{ “type”: “STRING”, “value”:“002”},{ “type”: “DATE”, “value”:“2007-12-03”}
// Определение РЗ
SELECT oktmo, formalname, startdate, enddate FROM datamart.9.1.addrobj WHERE areacode=? and citycode=? and startdate>=?
Регламентированный SQL-запрос без параметров:
// Исходный запрос от Потребителя данных ПОДД СМЭВ:
select * from egrul.1.1.legalentity_view()
// Пример преобразования исходного запроса в соответствии с загруженным определением Регламентированного SQL-запроса:
select ogrn, short_name, inn, kpp, region_code from egrul.2.legalentity
Распределенный Регламентированный SQL-запрос:
// Исходный запрос от Потребителя данных ПОДД СМЭВ:
select * from podd.1.1.r_query(‘Москва’, 18)
// Пример преобразования исходного запроса в соответствии с загруженным определением Регламентированного SQL-запроса:
select ao.oktmo, o.name, o.kod from fias.1.0.addrobj ao LEFT JOIN oktmo.1.0.oktmo o on ao.oktmo = o.kod2 WHERE ao.offname= ‘Москва’ AND o.regionid = 18
3.3.3. Выполнение запроса с системным параметром
Системные параметры не описываются в определении Регламентированного SQL-запроса и могут быть заданы Потребителем для любого Регламентированного SQL-запроса при выполнении запроса.
Таблица 3.4 содержит поддерживаемые в ПОДД СМЭВ параметры.
№ |
Мнемоника |
Назначение |
|---|---|---|
1 |
settings_for_system_time |
Системный параметр для получения актуальных на заданный момент данных. Позволяет указывать при вызове запроса момент времени, на который требуется получить актуальные данные из Витрины. |
2 |
settings_for_system_time_started |
Системный параметр для получения результата выполнения запроса с данными, добавленными за указанный диапазон времени. Позволяет указывать при вызове запроса диапазон номеров дельт, за который требуется получить измененные данные |
3 |
settings_for_system_time_finished |
Системный параметр для получения результата выполнения запроса с данными, удаленными за указанный диапазон времени. Позволяет указывать при вызове запроса диапазон номеров дельт, за который требуется получить удаленные данные |
Вызов Регламентированного SQL-запроса с системным параметром осуществляется аналогично вызову Регламентированного SQL-запроса с заданием значения для именованного параметра, в соответствии со следующими правилами:
Параметр задается в запросе только один раз в виде именованного параметра с соответствующей мнемоникой.
Значение параметра
settings_for_system_timeдолжно соответствовать форматуYYYY-MM-DD hh:mm:ss.Значение параметров
settings_for_system_time_startedиsettings_for_system_time_finishedдолжно соответствовать формату (int1,int2). Значениеint1должно быть меньше, чемint2.Задание параметра недоступно при вызове Регламентированного SQL-запроса без SQL-выражения.
Для простого запроса: для Витрины, к которой обращается Регламентированный SQL-запрос с данным параметром, должна быть задана настройка поддержки обработки данного параметра в соответствии с «Руководством администратора Агента СМЭВ4». [28]
Для распределенного запроса: для всех Витрин, к которым обращается Регламентированный SQL-запрос с данным параметром, должна быть задана настройка поддержки обработки данного параметра в соответствии с «Руководством администратора Агента СМЭВ4».
В подзапросе в блоке FROM должна отсутствовать конструкция «FOR SYSTEM_TIME».
Пример вызова с параметром settings_for_system_time:
// вызываемый SQL-запрос (вариант 1)
select * from fias.1.0.addrobj_func(p1=>'000', p2=>'001', settings_for_system_time=>'YYYY-MM-DD hh:mm:ss')
// вызываемый SQL-запрос (вариант 2)
select * from fias.1.0.addrobj_func(settings_for_system_time=>?, p1=>?, p2=>?)
params: {"type": "TIMESTAMP", "value": "YYYY-MM-DD hh:mm:ss"},{"type": "STRING", "value": "001"},{"type": "STRING", "value": "002"}
// SQL-выражение Регламентированного SQL-запроса
SELECT <атрибуты> FROM <витрина>.<таблица> WHERE id=:p1 AND region=:p2
Пример вызова с параметрами settings_for_system_time_started и settings_for_system_time_finished:
// вызываемый SQL-запрос (вариант 1)
select * from fias.1.0.addrobj_func(p1=>'000', p2=>'001', settings_for_system_time_started=>'122,124')
select * from fias.1.0.addrobj_func(p1=>'000', p2=>'001', settings_for_system_time_finished=>'122,124')
// вызываемый SQL-запрос без настроек через JDBC-интерфейс
call fias.1.0.addrobj_func(p1=>'000', p2=>'001', settings_for_system_time_started=>'122,124')
// вызываемый SQL-запрос с параметрами, передаваемыми отдельным блоком
select * from fias.1.0.addrobj_func(settings_for_system_time_finished=>?, p1=>?, p2=>?)
params: {"type": "STRING", "value": "122,124"},{"type": "STRING", "value": "001"},{"type": "STRING", "value": "002"}
// SQL-выражение РЗ
SELECT <атрибуты> FROM <витрина>.<таблица> WHERE id=:p1 AND region=:p2
3.3.4. Выполнение запросов с использованием табличных параметров, передаваемых Потребителем данных для обогащения
Выполнение запроса, включающего табличный параметр, осуществляется аналогично выполнению любого запроса к Витрине Поставщика данных. Описание синтаксиса выполнения запроса приведено в Раздел 3.1.
Для выполнения запроса с табличным параметром необходимо:
Определить структуру таблицы, указанной в табличном параметре.
Указать запрос, содержащий табличный параметр.
Указать источник данных для табличного параметра.
Эти операции могут быть выполнены с использованием REST или JDBC-интерфейса.
3.3.4.1. Запрос с использованием REST-интерфейса
При использовании REST-интерфейса данные собираются в CSV файл, который прикрепляется к запросу, содержащему информацию о структуре таблицы и SQL-выражение. Формат запроса приведен в Раздел 2.3.1.2.
В теле запроса передаются следующие параметры:
sql:SELECT el.inn, er.region_name FROM @inns el LEFT JOIN egrul.2.region_codes er ON SUBSTRING(el.inn,1,2) = er.region_code
priority:NORMAL
tableParams:{“name”: “inns”, “columns”:[{“name”: “id”, “type”: “INTEGER”},{“name”: “inn”, “type”: “STRING”}]}
inns:<l.csv>
где:
sql – текст для вызова Регламентированного SQL-запроса, содержащего табличные параметры;
tableParams – описание передаваемого файла с данными для табличного параметра, где:
name – табличный параметр;
columns – перечень названий столбцов и их типов, содержащихся в файле с данными для табличного параметра.
inns – файл с данными для табличного параметра, где:
inns – табличный параметр (выступает в качестве названия параметра запроса);
<1.csv> – файл в формате CSV (поддерживаемый формат), передаваемый в параметре запроса.
Пример CSV файла (разделитель – запятая):
1, 4345310593
2, 4311003795
3, 4345336320
3.3.4.2. Запрос с использованием JDBC-интерфейса
При использовании JDBC-интерфейса для описание передаваемой в качестве параметра таблицы и добавления данных расширяются функции драйвера JDBC. Для доступа к данным формируется итератор.
После передачи данных выполняется запрос, включающий табличный параметр в формате @имя_параметра.
Пример использования представлен в Раздел 2.3.3.1.
3.3.5. Получение двоичных объектов в результатах запроса
ПОДД СМЭВ предоставляет возможность получения в качестве результата выполнения Регламентированных SQL-запросов:
скалярных параметров (значение которых представляет собой число, строку или дату);
двоичных объектов (соответствующих файлам, размещенным на Витринах Потребителей данных).
Для получения в качестве ответа двоичных объектов необходимо выполнение следующих условий:
Витрина Поставщика данных поддерживает тип данных «двоичный объект»;
в метаданных Витрины Поставщика данных, зарегистрированной в ПОДД СМЭВ, для соответствующих атрибутов должен быть установлен тип данных «двоичный объект» (описание типов данных ПОДД СМЭВ приведено в Раздел 1.5.5).
Процесс выполнения такого SQL-запроса приведён на рисунке 14, описание процесса приведено далее.
ИС Потребителя передаёт SQL-запрос в Агент СМЭВ4.
Далее приём, обработка и передача запроса:
Агент Потребителя данных → Ядро ПОДД СМЭВ → Агент Поставщика данных → Витрина Поставщика данных осуществляется аналогично обычному информационному обмену с использованием Регламентированных SQL-запросов (Раздел 1.4.1).
Витрина данных осуществляет обработку запроса и возвращает ответ.
В случае выполнения запроса, результат которого содержит атрибуты с типом данных «двоичный объект», в составе результата запроса атрибут может принимать одно из следующих возможных значений:
непосредственно сам двоичный объект;
уникальная ссылка на получение двоичного объекта с Витрины Поставщика данных (см. шаги Рисунок - 3.1).
Решение о том какое значение будет передано (объект или ссылка на него принимается Витриной данных).
Далее ответ доставляется до ИС Потребителя аналогично обычному обмену (Раздел 1.4.1).
Пример возврата двоичного объекта и ссылки на двоичный объект приведен в Раздел 2.3.1.1.3.
Если в результате выполнения запроса передана ссылка, то для получения двоичного объекта ИС Потребителя направляет запрос на получение вложения по ссылке, которую получил в ответе.
Запрос двоичного объекта по ссылке считается отдельным обменом, идентификатор обмена (requestId) запроса по ссылке уникальный (в случае нескольких ссылок - уникальный для каждой из ссылок).
Описание запроса на получение двоичного объекта по ссылке:
через REST-интерфейс приведено в Раздел 2.3.1.3;
через JDBC-интерфейс приведено далее.
Далее приём, обработка и передача запроса Агент Потребителя данных → Ядро ПОДД СМЭВ → Агент Поставщика данных → Витрина Поставщика данных осуществляется аналогично обычному обмену (Раздел 1.4.1). Для передачи запроса двоичного объекта на Витрину Поставщика используется специальный топик
blob.rq.В случае, если в теле запроса содержится ссылка на двоичный объект:
Адаптер PODD Витрины данных отправляет запрос в BLOB-адаптер на получение этого файла.
BLOB-адаптер, считывает ссылку на двоичный объект и обращается в Хранилище BLOB-объектов на стороне Ведомства.
После получения двоичного объекта, возвращает его в ПОДД СМЭВ.
Для передачи ответа на запрос двоичного объекта от Витрины Поставщика данных используется специальные топики
blob.rsиblob.err.ПОДД СМЭВ передает ИС Потребителя данных двоичный объект (файл), организуя двоичный поток между Витриной Поставщика данных и ИС Потребителя данных.
В процессе передачи Агент Поставщика данных разбивает поток данных на сегменты (чанки) и подписывает каждый сегмент подписью Поставщика данных. Перед передачей данных Потребителю данных подпись проверяется Ядром ПОДД СМЭВ.
Пример программного кода для JDBC-драйвера, реализующего получение двоичного объекта:
package dev.nsud.jdbc
import org.junit.jupiter.api.Test
import java.sql.Connection
import java.sql.DriverManager
import org.junit.jupiter.api.Assertions
import java.sql.SQLException
class Features {
private getConnectionURI() {
val host = System.getProperty(“agent.host”, “localhost”)
val port = System.getProperty(“agent.port”, “8182”)
return “jdbc:podd://$host:$port”
}
@Test
fun `ожидается успешное соединение с базой данных`() {
Assertions.assertDoesNotThrow { DriverManager.getConnection(getConnectionURI()) }
}
@Test
fun `ожидается успешное получение бинарных данных `() {
Assertions.assertDoesNotThrow {
val expect = getExpectedBytes()
val con = DriverManager.getConnection(getConnectionURI())
val statement = con.createStatement()
statement.executeQuery(“select binaryColumn from datamart.table where id=1”)
val resultSet = statement.resultSet
Assertions.assertEquals(expect, resultSet.getBlob(0))
}
}
}
Рисунок - 3.1 Информационный обмен при выполнении запроса с использованием ПОДД СМЭВ
3.3.6. Получение печатной формы в результатах запроса
Запросы для получения печатной формы в результатах запроса не содержат SQL-выражения в определении Регламентированного SQL-запроса и являются процедурами, выполняемыми на стороне Витрины. Вызов запроса от ИС Потребителя аналогичен вызову обычного Регламентированного SQL-запроса.
Приём, обработка и передача запроса по пути Агент Потребителя данных → Ядро ПОДД СМЭВ → Агент Поставщика данных осуществляется аналогично обычному информационному обмену с использованием Регламентированных SQL-запросов (Раздел 1.4.1). Особенностью обработки запросов является добавление Агентом Поставщика данных алиаса сертификата в запрос, согласно настройкам, заданным в соответствии с «Руководством администратора Агента СМЭВ4» [28], для последующей подписи печатной формы.
3.4. Выполнение запросов к REST-сервису ИС Ответчика
Для выполнения запроса к REST-сервису ИС Ответчика необходимо:
Определить доступные REST-сервисы.
Составить URI запроса в соответствии со спецификацией OpenAPI зарегистрированного REST-сервиса ИС Ответчика, загруженной в ПОДД СМЭВ.
URI запроса формируется путём конкатенации мнемоники Агента Ответчика, префикса в URL (basePath) соответствующего REST-сервиса ИС Ответчика и path операции. Сформированный запрос должен совпадать с запросом из спецификации OpenAPI.
Формат запроса для обмена с использованиям REST-сервиса ИС Ответчика имеет вид:
<HTTP-метод> <адрес>:<порт>/<systemMnemonic><basePath><path>
где:
HTTP-метод – метод из поддерживаемых REST-сервисом;
<адрес> – IP-адрес Агента Инициатора;
<порт> – порт для обращения Агента Инициатора к Ядру ПОДД СМЭВ в соответствии с «Руководством администратора ПОДД СМЭВ» [28];
systemMnemonic – мнемоника Агента Ответчика, на стороне которого развернут REST-сервис;
basePath – префикс в URL соответствующего REST-сервиса ИС Ответчика;
path – путь операции, указанный в спецификации OpenAPI соответствующего REST-сервиса ИС Ответчика.
Пример URI запроса соответствует примеру спецификации OpenAPI, приведенному в Раздел 1.5.5 данного документа:
GET 10.81.4.30:29164/agent-oktmo/region-service/region/123
Выполнение запросов осуществляется через REST-интерфейс Агента СМЭВ4 (см. Раздел 2.3.1.3 данного документа).
3.5. Сквозная идентификация запросов
Для диагностики проблем возникающих в ходе информационных обменов через ПОДД СМЭВ в части отслеживания всей цепочки сообщений, возникающих в ходе информационного обмена обеспечена сквозная идентификация запросов.
Сквозная идентификация в ПОДД СМЭВ основывается на идентификаторах, приведённых в Таблица 3.5.
На Рисунок - 3.2, Рисунок - 3.3 и Рисунок - 3.4 приведён порядок возникновения этих идентификаторов.
№ |
Вид |
Код |
Источник идентификатора |
|---|---|---|---|
1 |
Клиентский идентификатор (идентификатор клиента) |
clientRequestId |
Инициатор обмена |
2 |
Идентификатор обмена (идентификатор процесса) |
requestId |
ПОДД СМЭВ при получении запроса на:
Витрина данных:
|
3 |
Идентификатор подзапроса ПОДД СМЭВ – Витрина |
subRequestId |
ПОДД СМЭВ |
4 |
Идентификатор подзапроса Адаптер – Prostore |
dataRequestId |
Адаптер Витрины |
Рисунок - 3.2 Сквозная идентификация запросов для информационного обмена с использованием регламентированных SQL-запросов
Рисунок - 3.3 Сквозная идентификация запросов для информационного обмена с использованием запросов к REST-сервису ИС Ответчика
Рисунок - 3.4 Сквозная идентификация запросов для информационного обмена с использованием Рассылок
Правила использования клиентского идентификатора
Клиентский идентификатор опционален.
Исключение из правила – УВ явно добавил обязательное поле ClientRequestID в спецификацию OpenAPI для информационного обмена с использованием Регламентированных REST-запросов. В данном случае, валидация осуществляется в соответствии со спецификацией.
Клиентский идентификатор должен соответствовать стандарту UUID.
Ответственность за используемый формат несёт инициатор обмена. ПОДД не осуществляет проверку по формату и версиям UUID.
Исключение из правила – УВ явно добавил поле ClientRequestID в спецификацию OpenAPI для информационного обмена с использованием Регламентированных REST-запросов. В данном случае, валидация осуществляется в соответствии со спецификацией.
Допустимо использовать один клиентский идентификатор для связывания нескольких запросов. ПОДД СМЭВ не осуществляет проверку на уникальность.
Способ передачи клиентского идентификатора приведён в Раздел 2.3.
3.6. Лимитирование регламентированных запросов Потребителя к информационным ресурсам Поставщика
3.6.1. Лимиты
Для защиты Поставщиков от избыточных запросов Потребителей обеспечена возможность лимитирования запросов к Поставщику данных от конкретного Потребителя данных для информационных обменов с использованием регламентированных запросов.
Лимит может быть установлен на следующие информационные ресурсы Поставщика:
на конкретный Регламентированный SQL-запрос;
на все Регламентированные SQL-запросы к конкретной Витрине;
на конкретный Регламентированный REST-запрос (спецификацию OpenAPI ИС Поставщика);
общий на все Регламентированные SQL и REST-запросы от ИС Потребителя к ИС Поставщика.
Лимит может быть следующих типов:
на Количество запросов;
на Размер запросов;
на Размер ответов.
При создании лимита указывается его значение (количество или размер) и период (у которого два назначения – период контроля соблюдения значения и период блокировки).
3.6.2. Условия для добавления лимитов
В ПОДД должны быть зарегистрированы ИС Поставщика и ИС Потребителя;
Если лимит задаётся на Витрину в ПОДД СМЭВ должны быть:
зарегистрирована Витрина;
Витрина связана с ИС Поставщика;
Если лимит задаётся на конкретный Регламентированный SQL-запрос, в ПОДД СМЭВ должны быть:
зарегистрирована Витрина;
Витрина связана с ИС Поставщика;
выданы права ИС Потребителя на Регламентированный SQL-запрос.
Если лимит задаётся на конкретную спецификацию OpenAPI в ПОДД СМЭВ должны быть:
зарегистрирована спецификация OpenAPI;
выданы права ИС Инициатора на спецификацию OpenAPI.
При выставлении лимитов недопустимо совмещение:
общего на все Регламентированные SQL и REST-запросы ИС Потребителя к ИС Поставщика лимита и лимита на другие ресурсы;
лимита на Витрину и лимита на Регламентированный SQL-запрос к этой Витрине.
Лимит на конкретный Регламентированный SQL-запрос ограничивает запросы Потребителя по всем версиям этого запроса.
Лимит на все Регламентированные SQL-запросы к конкретной Витрине ограничивает запросы Потребителя по всем версиям модели этой Витрины.
При установке лимита на Витрину и ИС также могут учитываться произвольные SQL-запросы. Реализация исключения таких запросов из процесса лимитирования не предусмотрена, так как права доступа на выполнение произвольных SQL-запросов предоставляются автоматически и только владельцам Витрин на их собственные Витрины.
3.6.3. Блокировки
В случае превышения лимитов, заданных Поставщиком, ПОДД СМЭВ блокирует Потребителю доступ к соответствующему информационному ресурсу. Например, если для ИС Потребителя указано два лимита к двум Регламентированным SQL-запросам и заблокирован доступ к одному из них, она может продолжить пользоваться другим доступным запросом. При получении запроса от заблокированного Потребителя, ПОДД СМЭВ возвращает ответ с соответствующей ошибкой. Блокировка снимается:
при истечении времени блокировки;
при удалении соответствующего лимита;
при редактировании соответствующего лимита (любых атрибутов кроме наименования);
при получении запроса на принудительное снятие блокировки.
3.6.4. Управление лимитами и блокировками
Управление лимитами и блокировками доступно из ЛК УВ.
3.6.5. Алгоритм лимитирования
Лимитирование осуществляется в соответствии со следующим алгоритмом (Рисунок - 3.5):
ПОДД СМЭВ формирует окна наблюдения от 1 января 1970 года 00:00:00.000 в соответствии с указанным значением периода лимита.
ПОДД СМЭВ хранит в памяти значение счётчика предыдущего и текущего окна наблюдения. После разблокировки значения счётчиков обнуляются.
ПОДД СМЭВ вычисляет счётчик инкрементируя значение при каждом полученном запросе.
ПОДД СМЭВ принимает решение о блокировке на основании имеющихся счётчиков:
Если значение предыдущего окна наблюдения нет, то берётся значение инкрементированного счётчика текущего окна.
Если полученное значение меньше значения лимита, то запрос будет обработан.
Если значение предыдущего окна наблюдения есть, то ПОДД СМЭВ вычисляет коэффициенты наложения окна наблюдения на интервалы по формуле:
K = N + M * R
где:
- N - количество запросов в текущем интервале (с учетом полученного),
- M - количество запросов на предыдущем интервале,
- R - коэффициент наложения на предыдущий интервал (0...1).
Если полученное значение меньше значения лимита, то запрос будет обработан.
Пример:
Установлен лимит: 4 запроса в минуту
С 0 до 0:59 - пришло 5 запросов,
В 1:30 - пришёл ещё один запрос
результат вычисления:
- N = 1,
- M = 5,
- R = (90 - 60) / 60 = 0.5
K = 1 + 5 * 0.5 = 3.5 меньше предельного, запрос будет обработан.
Рисунок - 3.5 Алгоритм лимитрирования запросов