2. Описание подключения к ПОДД СМЭВ
2.1. Протокол ПОДД СМЭВ
Взаимодействие Агентов ПОДД СМЭВ и Ядра ПОДД СМЭВ реализовано c использованием Протокола ПОДД СМЭВ, который представляет собой (в зависимости от вида информационного обмена):
Бинарный протокол Apache Pulsar с предварительной аутентификацией.
Бинарный протокол Rsocket.
Бинарный протокол Apache Pulsar – протокол, реализующий команды, которыми обмениваются между собой клиент (Агент ПОДД СМЭВ) и брокер Apache Pulsar в составе ПОДД СМЭВ. Команды имеют формат, базирующийся на Protocol Buffers (protobuf). Набор данных, пересылаемый ПОДД СМЭВ по этому протоколу, кодируется в формат Apache Avro.
В рамках предварительной аутентификации клиенты (Агенты ПОДД СМЭВ), устанавливающие подключение по бинарному протоколу Apache Pulsar, получают аутентификационный токен с использованием OpenID Connect (OIDC) – протокола, базирующегося на Oauth 2.0.
2.2. Подключение участников взаимодействия с использованием ПОДД СМЭВ
Основным способом направления обращений является использование Личного кабинета СЦ https://sc.minsvyaz.ru.
Электронная почта sd@sc.minsvyaz.ru является резервным способом направления обращений, который используется в случае недоступности Личного кабинета СЦ.
Более подробная информация о порядке подключения к СМЭВ 4 приведена в документе «Регламент подключения к СМЭВ 4» [1].
2.3. Протокол взаимодействия Агента ПОДД СМЭВ и Витрины Поставщика данных
Агент ПОДД СМЭВ Поставщика данных может взаимодействовать с несколькими Витринами данных. Протокол коммуникации Агента и Витрин реализован в виде обмена сообщениями с использованием зарезервированных топиков брокера сообщений Apache Kafka.
2.3.1. Перечень заголовков сообщений в Apache Kafka
При обработке всех видов сообщений Витрины должны прокидывать заголовки Kafka сообщения из запроса в соответствующий ответ, как в успешный, так и в ошибочный.
tab_provider_kafka_message_headings содержит перечень заголовков, которые необходимо прокидывать.
Заголовок |
Описание |
|---|---|
REQUEST_ID |
Идентификатор запроса |
AGENT_CONSUMER_ID |
Идентификатор Агента ПОДД (соответствует мнемонике ИС) |
QUERY_MNEMONIC |
<Полная мнемоника Регламентированного SQL-запроса>.<версия Регламентированного SQL-запроса> |
TIMESTAMPS |
Временная метка с описанием событий, представляет собой склейку сериализованных в JSON
структур типа TimestampData ( Пример: {«name»:»REQUEST_RECEIVED_BY_AGENT_CONSUMER», «timestamp»:1654590839986,»source»:»test»,»result»:»UNDEFINED»}; {«name»:»REQUEST_RECEIVED_BY_AGENT_CONSUMER», «timestamp»:1654590842487,»source»:»test»,»result»:»SUCCESS»} |
CORE_ID |
Идентификатор Ядра |
MESSAGE_TYPE |
Тип сообщения <Имя класса, используемого для соответствующего сообщения>:0.1 |
QUERY_DEADLINE |
Время в миллисекундах от эпохи, до которого запрос должен быть выполнен |
Атрибут |
Описание |
|---|---|
name |
Название временной метки:
отправкой результата Потребителю (Executor/Strom)) |
timestamp |
UTC время в миллисекундах |
source |
Сервис, зафиксировавший временную метку |
result |
Результат обработки:
|
2.3.2. Перечень топиков брокера сообщений Apache Kafka
Конфигурация Агента содержит перечень Витрин данных, с которыми он взаимодействует. Каждой Витрине в зависимости от настроек конфигурации, заданных в соответствии с «Руководством администратора ПОДД СМЭВ » соответствует один из наборов топиков:
Набор топиков, создаваемый по умолчанию. Полное название топиков формируются по шаблону <префикс для динамически регистрируемых Витрин>.<название топика>. По умолчанию префикс отсутствует.
Дополнительный набор топиков. Полное название топиков формируются по следующему шаблону <префикс для статически регистрируемых Витрин>.<название топика>. По умолчанию создаются отдельные группы топиков для каждой схемы Витрины с префиксом, соответствующим мнемонике Витрины.
Названия топиков брокера сообщений приведены в tab_broker_topics_name.
Приложение 2 Структуры сообщений для взаимодействия с Поставщиком содержит структуры сообщений для обмена данными с использованием топиков.
№ |
Топик |
Публикатор |
Подписчик |
Передаваемый объект |
|---|---|---|---|---|
Топики регистрации и настройки Витрин |
||||
1 |
datamart.signal |
Витрина |
Агент |
Сообщение с регистрационными данными Витрины |
2 |
<префикс>.profile.rq |
Агент |
Витрина |
Запрос профиля Витрины |
3 |
<префикс>.profile.rs |
Витрина |
Агент |
Профиль Витрины |
4 |
<префикс>.profile.err |
Витрина |
Агент |
Ошибка при выполнении запроса профиля Витрины |
5 |
<префикс>.signal |
Агент |
Витрина |
Сообщение с итогами выполнения регистрации Витрины |
Топики для обеспечения информационного обмена с использованием SQL-запросов |
||||
6 |
<префикс>.query.rq |
Агент |
Витрина |
Подзапрос |
7 |
<префикс>.procedure.query.rq |
Агент |
Витрина |
Регламентированный запрос на исполнение |
8 |
<префикс>.query.tp |
Агент |
Витрина |
Подзапрос с использованием табличного параметра |
9 |
<префикс>.query.tp.bin |
Агент |
Витрина |
Подзапрос с использованием табличного параметра (при бинарном разбиении на чанки) |
10 |
<префикс>.query.rs |
Витрина |
Агент |
Результата подзапроса |
11 |
<префикс>.query.estimation.rs |
Витрина |
Агент |
Оценка (статистика) по исполнению подзапросов |
12 |
<префикс>.query.err |
Витрина |
Агент |
Ошибка при выполнении подзапроса |
13 |
<префикс>.blob.rq |
Агент |
Витрина |
Запрос двоичных данных по ссылке |
14 |
<префикс>.blob.rs |
Витрина |
Агент |
Результат запроса двоичных данных по ссылке |
15 |
<префикс>.blob.err |
Витрина |
Агент |
Ошибка при выполнении запроса двоичных данных по ссылке |
16 |
<префикс>.cancel.rq |
Агент |
Витрина |
Идентификатора запроса, выполнение которого в Витрине нужно отменить |
17 |
<префикс>.cancel.rs |
Витрина |
Агент |
Результат успешной отмены запроса |
18 |
<префикс>.cancel.err |
Витрина |
Агент |
Ошибка при выполнении отмены запроса |
Топики для обеспечения информационного обмена с использованием Рассылок |
||||
19 |
<префикс>.replication.rq |
Агент |
Витрина |
Информация о подписке |
20 |
<префикс>.replication.rs |
Витрина |
Агент |
Структура данных для хранения данных по подписке |
21 |
<префикс>.replication.err |
Витрина |
Агент |
Ошибка при обработке подписки |
22 |
<префикс>.delta.rq |
Агент |
Витрина |
Запрос пакета дельт по подписке |
23 |
<префикс>.delta.tp |
Агент |
Витрина |
Запрос на пересечение ключей и дельт по пересечённым ключам |
24 |
<префикс>.delta.rs |
Витрина |
Агент |
Дельта по подписке |
25 |
<префикс>.delta.err |
Витрина |
Агент |
Ошибка при формировании Витриной дельты по подписке |
26 |
<префикс>.replication.cancel.rq |
Агент |
Витрина |
Идентификатора отменяемой подписки |
27 |
<префикс>.replication.cancel.rs |
Витрина |
Агент |
Результат (успешный или ошибка) отмены подписки |
28 |
<префикс>.delta.notification |
Витрина |
Агент |
Уведомление о наличии дельты по подписке в Витрине Поставщика |
Топики для получения статистики по Витринам |
||||
29 |
<префикс>.statistic.rq |
Агент |
Витрина |
Запрос статистики таблиц |
30 |
<префикс>.statistic.rs |
Витрина |
Агент |
Статистика таблиц |
31 |
<префикс>.statistic.err |
Витрина |
Агент |
Ошибка формировании статистики таблиц |
Топики для получения событий Витрины |
||||
32 |
<префикс>.scl.signal |
Витрина |
Агент |
События Витрины для дальнейшей передачи в СЦЛ |
2.3.3. Настройка Агента ПОДД для работы с несколькими Витринами данных
В ПОДД предусмотрено два способа регистрации Витрин данных:
на основе сообщений от Витрин;
на основе конфигурационного файла.
Регистрация Витрины осуществляется вне зависимости от наличия загруженных в ПОДД метаданных Витрин (Раздел 1.5.2). Выполнение запросов к Витринам возможно только после успешной регистрации Витрины и получения метаданных в ПОДД СМЭВ.
2.3.3.1. Регистрация на основе конфигурационного файла
Поддерживается на стороне Потребителя и Поставщика. tab_provider_config_register содержит описание процесса регистрации Витрины.
Процесс |
Шаг |
Описание |
|---|---|---|
Инициация регистрации |
1 |
При запуске Агент вычитывает локальный конфигурационный файл [2] с настройками регистрации Витрин. Витрина может быть зарегистрирована:
и создает согласно настройкам в конфигурационном файле:
|
2 |
Если одному из Агентов приходит сообщение из Ядра для незарегистрированной Витрины, Агент регистрирует её динамически (и при необходимости создает группу топиков по умолчанию). |
|
3 |
Если инициатором сообщения будет Витрина или ИС Потребителя, они будут зарегистрированы динамически, если при старте Агента создана группа топиков по умолчанию. |
|
Регистрация |
4 |
Агент загружает профиль Витрины. Способ загрузки определяется значением registrationFlow в конфигурационном файле:
|
5 |
Витрина данных передаёт:
|
|
6 |
Агент, получивший запрос от Витрины:
Витрины,
|
|
7 |
Ядро ПОДД: осуществляет регистрацию |
|
8 |
Направляет в Агент подтверждение регистрации Витрины. При успешном выполнении всех регистрационных операций, либо если данная Витрина уже зарегистрирована возвращается статус «успех», в противном случае «не успех». |
|
Действия после успешной Регистрации |
9 |
Агент (при запуске) вычитывает метаданные Витрин из Ядра ПОДД через специальный топик. Чтение метаданных не препятствует запуску, то есть в процессе чтения Агент уже может принимать запросы. Обновление метаданных производится при каждом перезапуске Агента |
Действия после не успешной Регистрации |
10 |
Агент завершает работу с ошибкой |
Описание приведено в Руководстве администратора Агента ПОДД СМЭВ, размещенном на портале ЕСКС – https://info.gosuslugi.ru/
2.3.3.2. Регистрация на основе сообщений Витрин
Только для Поставщика.
tab_provider_datamart_register содержит описание процесса регистрации Витрины, схема регистрации на основе
сообщения от Витрины приведена на img_provider_datamart_register.
Процесс |
Шаг |
Описание |
|---|---|---|
Инициация регистрации |
1 |
Витрина данных направляет в Агент сообщение с
регистрационными данными в общий топик Kafka При отправке запроса на регистрацию Витрина должна обеспечить
подписку на топик |
Регистрация |
2 |
Агент создаёт необходимые для работы с новой Витриной данных
топики в соответствии с |
3 |
Агент запрашивает у Витрины профиль через топик |
|
4 |
Агент получает:
|
|
5 |
Агент:
|
|
6 |
Агент получает подтверждение регистрации профиля Витрины от Ядра ПОДД СМЭВ. При успешном выполнении всех регистрационных операций, либо если данная Витрина уже зарегистрирована возвращается статус «успех», в противном случае «не успех». |
|
7 |
Агент направляет Витрине сообщение о статусе регистрации. Структура сообщения приведена в Приложение 2 Структуры сообщений для взаимодействия с Поставщиком |
|
8 |
В случае неуспешной регистрации Агент удаляет созданные на шаге 2 топики в Kafka. |
|
Действия после успешной Регистрации |
9 |
Агент выполняет запрос к Ядру ПОДД СМЭВ за актуальной информацией о зарегистрированных Витринах (метаданные Витрины и иные данные, необходимые для корректной работы) [3] и обновляет по полученным данным хранимую локально сводную информацию. Агент завершает процедуру запуска только после получения актуальных данных. |
Действия после неуспешной Регистрации |
10 |
В случае ошибок, таймаутов и сбоев, инициация повторной регистрации обеспечивается Витриной. |
Данная информация используется Агентом при работе и обновляется на основе актуальных данных от Ядра при каждом перезапуске.
Процесс регистрации Витрины данных на основе сообщения от Витрины данных
2.3.4. Последовательность исполнения SQL-запроса в контуре Поставщика данных
В контуре Поставщика данных Агент, получив подзапрос от Ядра ПОДД СМЭВ, инициирует выполнение подзапроса Витриной путем отправки сообщения в топик:
query.rq – для Регламентированного SQL-запроса с SQL выражением и произвольных SQL-запросов;
procedure.query.rq – для Регламентированного SQL-запроса без SQL выражения (вызов процедуры на стороне Витрины по мнемонике Регламентированного SQL-запроса);
query.tp / query.tp.bin – передача чанков табличных параметров к подзапросу.
На рисунке 15 приведена последовательность исполнения SQL-запроса в контуре Поставщика данных. Структура сообщений приведена в Раздел 2.3.5.
Последовательность исполнения SQL-запроса в контуре ИС Поставщика данных
2.3.5. Структуры сообщений для взаимодействия с Поставщиком
Описание структур сообщений для взаимодействия с Поставщиком приведены в Приложение 2 Структуры сообщений для взаимодействия с Поставщиком.
2.3.6. Примеры реализации взаимодействия с Агентом ПОДД СМЭВ с использованием брокера сообщений Apache Kafka
Далее приведены примеры программного кода, реализующие следующие процедуры с использованием брокера сообщений Apache Kafka:
получение запроса от Агента ПОДД СМЭВ;
передача результата Агенту ПОДД СМЭВ.
Пример проекта для реализации взаимодействия с Агентом приведен в Приложение 1 Пример проекта для реализации взаимодействия с Агентом ПОДД.
2.3.6.1. Получение запроса от Агента ПОДД СМЭВ
Пример программного кода для получения запроса от Агента ПОДД СМЭВ с использованием брокера сообщений Apache Kafka:
package ru.rtlabs.sample
import mu.KLogging
import org.apache.kafka.clients.consumer.ConsumerRecord
import org.apache.kafka.clients.consumer.KafkaConsumer
import org.apache.kafka.clients.producer.KafkaProducer
import org.apache.kafka.clients.producer.Producer
import ru.rtlabs.sample.messaging.MessageHandler
import ru.rtlabs.sample.query.QueryRequestMessageHandler
import ru.rtlabs.sample.tableParams.TableParamStorageStub
import java.time.Duration
import java.util.Properties
/**
* Пример конфигурации обработчиков сообщений от агента
*/
suspend fun main() {
val kafkaProperties = loadProperties("/kafka.properties")
val producer = KafkaProducer<ByteArray, ByteArray>(kafkaProperties)
val topicProperties = loadProperties("/topic.properties")
val handlers = mapOf<String, MessageHandler>(
queryRequestHandler(topicProperties, producer),
)
KafkaConsumer<ByteArray, ByteArray>(kafkaProperties).apply {
subscribe(handlers.keys)
}.use {
while (true) {
it.poll(Duration.ofMillis(1_000)).forEach { record ->
val topic = record.topic()
val handler = handlers[topic] ?: HandlerNotFound(topic)
handler.handle(record)
}
}
}
}
fun loadProperties(fileName: String) = Properties().apply {
this::class.java.getResourceAsStream(fileName).use {
load(it)
}
}
fun queryRequestHandler(topicProperties: Properties, producer: Producer<ByteArray, ByteArray>) = Pair(
topicProperties.getProperty("query.requestTopicName"),
QueryRequestMessageHandler(
producer = producer,
errorTopic = topicProperties.getProperty("query.errorTopicName"),
resultTopic = topicProperties.getProperty("query.resultTopicName"),
estimationTopic = topicProperties.getProperty("query.estimationTopicName"),
tableParamStorage = TableParamStorageStub(),
),
)
private class HandlerNotFound(val topic: String) : MessageHandler {
override suspend fun handle(message: ConsumerRecord<ByteArray, ByteArray>) {
logger.error { "Не сконфигурирован обработчик для топика $topic" }
}
companion object : KLogging()
}
2.3.6.2. Передача результата Агенту ПОДД СМЭВ
Пример программного кода для передачи результата выполнения запрос Агенту ПОДД СМЭВ с использованием брокера сообщений Apache Kafka:
package ru.rtlabs.sample.query
import org.apache.kafka.clients.producer.Producer
import org.apache.kafka.clients.producer.ProducerRecord
import ru.rtlabs.common.model.DatamartErrorType
import ru.rtlabs.common.model.KeyValueMessage
import ru.rtlabs.common.model.metadata.ColumnInfo
import ru.rtlabs.common.model.metadata.ColumnType
import ru.rtlabs.common.result.resultEncoder
import ru.rtlabs.common.serialization.AvroCodec
import ru.rtlabs.common.serialization.UUIDCodec
import ru.rtlabs.contract.datamart.query.*
import ru.rtlabs.contract.datamart.query.blob.BinaryReference
import ru.rtlabs.sample.messaging.RequestChunkedResultHandler
import ru.rtlabs.sample.messaging.putHeaders
import ru.rtlabs.sample.tableParams.TableParamStorage
import java.io.ByteArrayOutputStream
import java.math.BigDecimal
import java.nio.ByteBuffer
import java.time.LocalDate
import java.time.LocalDateTime
import java.util.UUID
/**
* Реализация обработчика входящих сообщений на выполнение
* sql запросов к базе
*/
class QueryRequestMessageHandler(
producer: Producer<ByteArray, ByteArray>,
errorTopic: String,
resultTopic: String,
private val estimationTopic: String,
private val tableParamStorage: TableParamStorage,
) : RequestChunkedResultHandler<
UUID,
DatamartExecuteQueryRequest,
DatamartExecuteQueryResultChunk,
DatamartExecuteQueryError,
>(
producer = producer,
requestKeyDecoder = UUIDCodec::decode,
requestDecoder = AvroCodec(DatamartExecuteQueryRequest.serializer()).decodeFunction(),
resultKeyEncoder = AvroCodec(DatamartExecuteQueryResultChunk.serializer()).encodeFunction(),
resultTopic = resultTopic,
errorKeyEncoder = { UUIDCodec.encode(it.subRequestId) },
errorEncoder = AvroCodec(DatamartExecuteQueryError.serializer()).encodeFunction(),
errorTopic = errorTopic
) {
override val logger = logger()
private val estimationCodec = AvroCodec(DatamartQueryEstimationResponse.serializer())
override suspend fun process(request: KeyValueMessage<UUID, DatamartExecuteQueryRequest>) {
val executeRequest = request.value
val initialSql = executeRequest.sql
logger.debug { "Входящий sql запрос [$initialSql]" }
val tableParams = executeRequest.tableParams
if (tableParams.isEmpty()) {
if (executeRequest.isForEstimation) {
respondEstimation(request)
} else {
respond(initialSql, request)
}
return
}
try {
waitUntilAllParametersLoaded(tableParams, executeRequest.subRequestId)
val resultSql = tableParamStorage.replaceTableParams(initialSql, tableParams)
logger.debug { "Sql запрос к исполнению с использованием табличных параметров [$resultSql]" }
respond(resultSql, request)
} finally {
deleteAllParameters(tableParams, executeRequest.subRequestId)
}
}
private fun respondEstimation(request: KeyValueMessage<UUID, DatamartExecuteQueryRequest>) {
val executeRequest = request.value
val estimation = DatamartQueryEstimationResponse(
requestId = executeRequest.requestId,
subRequestId = executeRequest.subRequestId,
estimatedRowCount = 100,
estimatedSize = 10_000,
estimatedTime = 117,
)
producer.send(
ProducerRecord(
estimationTopic,
UUIDCodec.encode(executeRequest.subRequestId),
estimationCodec.encode(estimation),
).putHeaders(request.headers),
)
}
private fun respond(sql: String, request: KeyValueMessage<UUID, DatamartExecuteQueryRequest>) {
logger.debug { "Выполняется sql запрос [$sql]" }
val streamTotal = 2
val chunkTotal = 3
val executeRequest = request.value
for (stream in 1..streamTotal) {
for (chunk in 1..chunkTotal) {
val resultValue = prepareResult(executeRequest.subRequestId)
val isLastChunk = chunk == chunkTotal
val resultKey = prepareResultKey(
request = executeRequest,
chunkNumber = chunk,
isLastChunk = isLastChunk,
streamNumber = stream,
streamTotal = streamTotal,
uncompressedSize = resultValue.size,
)
sendResult(KeyValueMessage(resultKey, resultValue, request.headers))
}
}
}
private suspend fun waitUntilAllParametersLoaded(tableParams: List<DatamartTableParam>, subRequestId: UUID) {
tableParams.forEach {
tableParamStorage.wait(subRequestId, it)
}
}
private suspend fun deleteAllParameters(tableParams: List<DatamartTableParam>, subRequestId: UUID) {
tableParams.forEach {
tableParamStorage.delete(subRequestId, it)
}
}
private fun prepareResultKey(
request: DatamartExecuteQueryRequest,
chunkNumber: Int,
isLastChunk: Boolean,
streamNumber: Int,
streamTotal: Int,
uncompressedSize: Int,
) = DatamartExecuteQueryResultChunk(
requestId = request.requestId,
subRequestId = request.subRequestId,
replyTo = request.replyTo,
chunkNumber = chunkNumber,
isLastChunk = isLastChunk,
streamNumber = streamNumber,
streamTotal = streamTotal,
isFragmented = true,
uncompressedSize = uncompressedSize,
)
private fun prepareResult(request: DatamartExecuteQueryRequest): ByteArray {
val metadata = listOf(
ColumnInfo("string_col", ColumnType.STRING),
ColumnInfo("long_col", ColumnType.LONG),
ColumnInfo("int_col", ColumnType.INTEGER),
ColumnInfo("big_decimal_col", ColumnType.BIG_DECIMAL),
ColumnInfo("double_col", ColumnType.DOUBLE),
ColumnInfo("float_col", ColumnType.FLOAT),
ColumnInfo("date_col", ColumnType.DATE),
ColumnInfo("timestamp_col", ColumnType.TIMESTAMP),
ColumnInfo("bool_col", ColumnType.BOOLEAN),
ColumnInfo("binary_col", ColumnType.BINARY)
)
val buf = ByteBuffer.wrap(ByteArray(4) { it.toByte() })
val reference = BinaryReference(
subRequestId = request.subRequestId,
path = "Высокое дерево на плече Подзорной Трубы, направление к С. от С.-С.-В.",
)
@Suppress("RemoveRedundantCallsOfConversionMethods")
val rows: List<Array<Any?>> = listOf(
arrayOf(
"s1",
1L,
1.toInt(),
BigDecimal.TEN.setScale(3) / BigDecimal("3"),
1.2,
1.2f,
LocalDate.parse("2007-12-03"),
LocalDateTime.parse("2007-12-03T10:15:30").plusNanos(123456),
true,
buf
),
arrayOf(
"s2",
2L,
2.toInt(),
BigDecimal.TEN.setScale(3) / BigDecimal("6"),
2.2,
2.2f,
LocalDate.parse("2007-12-03"),
LocalDateTime.parse("2007-12-03T10:15:30").minusNanos(654321),
true,
reference
),
arrayOf(null, null, null, null, null, null, null, null, null, null)
)
return ByteArrayOutputStream().apply {
resultEncoder(metadata, this).use { encoder ->
rows.forEach(encoder::append)
}
}.toByteArray()
}
override fun createError(
request: KeyValueMessage<UUID, DatamartExecuteQueryRequest>,
e: Exception,
type: DatamartErrorType?,
) = DatamartExecuteQueryError(
requestId = request.value.requestId,
subRequestId = request.value.subRequestId,
replyTo = request.value.replyTo,
errorCode = (type ?: DatamartErrorType.QUERY).code,
message = e.message ?: ""
)
}
2.4. Протокол взаимодействия Агента ПОДД СМЭВ и ИС Потребителя данных
Для обеспечения доступности данных Агент ПОДД СМЭВ предоставляет:
REST-интерфейс для выполнения запросов к Витринам Поставщиков данных (Раздел 2.4.1 данного документа);
REST-интерфейс для выполнения запросов к REST-сервису ИС Ответчика (Раздел 2.4.2 документа).
специализированный протокол для исполнения запросов к Витринам Поставщиков данных с использованием JDBC-интерфейса Агента ПОДД (Раздел 2.4.3 данного документа).
2.4.1. REST-интерфейс Агента ПОДД для SQL-запросов
В Агенте ПОДД СМЭВ реализована поддержка REST-интерфейса для выполнения запросов к Витринам Поставщиков данных.
URL-адрес для выполнения обращений к REST-интерфейсу имеет следующий формат: http://<адрес>:<порт>/query, где:
<адрес>– IP-адрес Агента ПОДД СМЭВ;<порт>– порт, на котором развернут REST-интерфейс в соответствии с «Руководством администратора ПОДД СМЭВ» [4].
Входные параметры, включая текст SQL-запроса (в случае обращения к Витринам Поставщиков данных), должны кодироваться в виде JSON-строки и передаваться в теле запроса.
Результат выполнения SQL-запроса передается в теле HTTP-ответа в виде JSON-строки. Файлы, передаваемые в составе результата выполнения SQL-запроса, включаются в JSON как строковые атрибуты, кодирующие содержимое передаваемого файла с использованием Base64.
Файлы в составе результата выполнения запроса BLOB по ссылке передаются в виде массива байт. Возможно выполнение запросов к Витринам Поставщиков данных:
в синхронном режиме (см. Раздел 2.4.1.1);
в асинхронном режиме (см. Раздел 2.4.1.2);
на получение BLOB по ссылке (см. Раздел 2.4.1.3).
Размещен на портале ЕСКС – https://info.gosuslugi.ru/
2.4.1.1. Выполнение SQL-запросов (синхронный режим)
В синхронном режиме получение результата осуществляется путем выполнения HTTP-запроса от ИС Потребителя к Агенту ПОДД.
В рамках HTTP-запроса (метод POST) передается SQL-запрос, в ответе возвращается результат выполнения SQL-запроса.
2.4.1.1.1. HTTP-запрос при подключении к Pulsar
№ |
Параметр |
Тип |
Обязательность |
Описание |
|---|---|---|---|---|
1 |
Тип запроса (Method) |
Да |
POST |
|
2 |
Путь (Path) |
Да |
<IP:port>/query |
|
header |
||||
1 |
Content-Type |
string |
Да |
application/x-www-form-urlencoded; charset=utf-8 |
2 |
Accept-version |
string |
Да |
Основная (major) часть версии (сейчас 1) |
3 |
ClientRequestID |
string |
Нет |
Клиентский идентификатор |
query |
||||
1 |
async |
boolean |
Нет |
Для синхронного режима выполнения запроса параметр должен отсутствовать или иметь значение False |
body |
||||
1 |
priority |
string |
Да |
Приоритет запроса. Варианты:
|
2 |
timeout |
string |
Нет |
|
3 |
sql |
string |
Да |
Текст SQL-запроса к Витринам Поставщиков данных |
4 |
params |
array |
Нет |
Параметры запроса |
4.1 |
type |
string |
Да |
Тип параметра |
4.2 |
value |
string |
Да |
Значение параметра |
5 |
maxRows |
string |
Нет |
Максимальное количество возвращаемых записей таблицы ответа. Если не задан, возвращаются все записи. |
Пример запроса:
POST «https://10.81.4.30:29354/query?async=false»
Accept-Version:1
Content-Type:application/x-www-form-urlencoded; encoding=utf-8
priority:NORMAL
timeout:60
sql:SELECT ao.oktmo, o.name, o.kod from fias.addrobj ao LEFT JOIN oktmo.oktmo o on ao.oktmo = o.kod2 WHERE ao.offname= ? AND o.regionid = ?
params:{ “type”: “STRING”, “value”:”Москва”},{ “type”: “INTEGER”, “value”: “18”}
2.4.1.1.2. HTTP-запрос при подключении к брокеру
№ |
Параметр |
Тип |
Обязательность |
Описание |
|---|---|---|---|---|
1 |
Тип запроса (Method) |
Да |
POST |
|
2 |
Путь (Path) |
Да |
<IP:port>/query |
|
Заголовки |
||||
1 |
Content-Type |
string |
Да |
application/x-www-form-urlencoded; charset=utf-8 |
2 |
Accept-version |
string |
Да |
Основная (major) часть версии (сейчас 1) |
3 |
ClientRequestID |
string |
Нет |
Клиентский идентификатор |
Тело сообщения |
||||
1 |
priority |
string |
Да |
Приоритет запроса. Варианты:
|
2 |
timeout |
string |
Нет |
|
3 |
datamart |
string |
Нет |
Витрина Поставщика данных, к которой производится обращение |
4 |
mnemonic |
string |
Нет |
Мнемоника РЗ, к которому производится обращение |
5 |
majorVersion |
int |
Нет Если не указана majorVersion и minorVersion, обращение к актуальной версии |
Версия РЗ, к которому производится обращение |
6 |
majorVersion |
int |
Нет Если не указана majorVersion и minorVersion, обращение к актуальной версии Если не указана minorVersion и указанана majorVersion, обращение к последней версии в рамках majorVersion |
Версия РЗ, к которому производится обращение |
7 |
params |
array |
Нет |
Параметры запроса |
7.1 |
type |
string |
Да |
Тип параметра |
7.2 |
value |
string |
Да |
Значение параметра |
Пример запроса:
POST «https://10.81.4.30:29354/regulated-query»
Accept-Version:1
Content-Type:application/x-www-form-urlencoded; encoding=utf-8
priority:NORMAL
timeout:60
datamart: fias
mnemonic: addrobj_view
majorVersion: 1
minorVersion: 0
2.4.1.1.3. Ответ на HTTP-запрос
Допустимые коды возврата:
200 – ок;
400 – ошибка в запросе, информация об ошибке содержится в параметре «error»;
403 – нет полномочий на выполнение запроса, в том числе при блокировке полномочий на стороне Поставщика (с отображением соответствующего текста ошибки);
406 – неподдерживаемая версия протокола (после внедрения поддержки обратной совместимости возвращается только для несуществующих версий);
429 – ИС УВ временно заблокирована в связи с превышением лимитов;
500 – системная ошибка (в связи в принятыми ограничениями по доступности код 500 предполагается только при сбое Агента);
503 – система временно недоступна, возможно повторить запрос через 50 мс.
№ |
Параметр |
Тип |
Обязательность |
Описание |
|---|---|---|---|---|
1 |
responseCode |
numeric |
Да |
Код возврата (HTTP-код) |
header |
||||
1 |
Content-Type |
string |
Да |
application/x-www-form-urlencoded; charset=utf-8 |
2 |
ClientRequestID |
string |
Нет |
Клиентский идентификатор |
body |
||||
1 |
created_at |
dateTime |
Да |
Время формирования ответа |
2 |
query_id |
string |
Да |
Идентификатор запроса |
3 |
rows |
array |
Нет |
Массив записей таблицы ответа (в случае если результат выполнения запроса в виде таблицы). При задании параметра «maxRows» ограничивается его значением |
3.1 |
array |
Да |
Массив значений. Возможным значением может быть содержимое файла, закодированное в формате BASE64 |
|
4 |
meta |
array |
Да |
Список полей результата |
4.1 |
name |
string |
Да |
Имя поля |
4.2 |
type |
string |
Да |
Тип поля |
Пример ответа с кодом возврата 200:
HTTP/1.1 200 OK
{
“created_at”: “2017-12-15T07:36:-03Z”,
“query_id”: “c005a0e7-0d26-4ce0-a1fa-10c8bdf4dfc5”,
“meta”: [
{
“name”: “count”,
“type”: “INTEGER”
}
],
«rows»: [
[
«4994»
]
]
}
Пример ответа при возврате BLOB и ссылки на BLOB:
HTTP/1.1 200 OK
{
"created_at": "2023-02-21T14:15:46Z",
"query_id": "1edb1f23-90c1-6b75-bd1a-914f21e14802",
"meta": [
{
"name": "id",
"type": "INTEGER"
},
{
"name": "name",
"type": "STRING"
},
{
"name": "logo_thumb",
"type": "BINARY"
}
],
"rows": [
При возврате BLOB:
[
"2",
"scala",
"R0lGODlhIAAPAPUAADcNCTgNCW0ZEW8aEnMbEnYcE3wdFH0dFIAeFIEeFIMfFYUfFZAiF5IiF5MiF5okGKEmGaYnGqsoG7YrHbgrHb0sHsUuH8cvH8gvINExIdIxIdcyItozItszItszI940I980I+A0I+A1I+E1I+E1JAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAACUAIf8LSW1hZ2VNYWdpY2sNZ2FtbWE9MC40NTQ1NQAsAAAAACAADwAABoDAknBILBqPSOInyTR+ntBlc1r6gECi0WcjDASoyI0GQ4EoCt3SN7k+MggCwiJySQ+9X7y66yV6MhocICQjfHlGendEISOEHxkVRImGfWqVQhYTEQ0GAwclAJR8lnmHQw8ICQ4SFx2Gr3h6sUMhVyMjIFJgSVFPu02+v8LDxMUlQQA7"
],
При возврате ссылки на BLOB:
[
"17",
"test",
"link://c005a0e7-0d26-4ce0-a1fa-10c8bdf4dfc5"
]
]
}
№ |
Параметр |
Тип |
Обязательность |
Описание |
|---|---|---|---|---|
1 |
responseCode |
numeric |
Да |
Код возврата (HTTP-код) |
header |
||||
1 |
Content-Type |
string |
Да |
application/vnd.ru.rtlabs.podd.agent+json; version=1.0; charset=utf-8 |
2 |
ClientRequestID |
string |
Нет |
Клиентский идентификатор |
body |
||||
1 |
created_at |
dateTime |
Да |
Время формирования ответа |
2 |
query_id |
string |
Да |
Идентификатор запроса |
3 |
error |
string |
Нет |
Текст ошибки |
Пример ответа с кодом возврата, отличным от 200:
HTTP/1.1 429 Too Many Requests
{
“created_at”: “2021-09-10T15:23:36Z”,
“query_id”: “1ec124b1-1aa6-66d6-9d40-f55438428f56”,
“error”: “RuntimeException: Ошибка во входящем потоке : CustomRSocketException: LIMIT_EXCEEDED: Запросы к Ядру ПОДД временно заблокированы до September 10, 2021 3:24:35 PM UTC, код причины блокировки=2, подробности: ‘Превышен лимит по количеству запросов lockId=fe462d49-3c5a-4350-8bf6-da155225c52f, userId=e92e3fd4-28d9-48e5-8079-e377b676c9b4 reqCountLimit=10, QueriesStatistic(totalSent=10, totalBytes=2870, totalRows=0, requestIds={1ec124b0-bce0-613b-9d40-c7c6585b14bc=287B, 1ec124b0-caa5-677c-9d40-ebd5d2c0409b=287B, 1ec124b0-d464-695d-9d40-bbafa86207b7=287B, 1ec124b0-dcd5-63ae-9d40-171562fc3a47=287B, 1ec124b0-e493-6a6f-9d40-174dab9e6065=287B, 1ec124b0-ec15-60a0-9d40-f300de6b4e34=287B, 1ec124b0-f6de-6451-9d40-51926f0b5d81=287B, 1ec124b0-fe95-65e2-9d40-e5e27f87babb=287B, 1ec124b1-0581-6d43-9d40-6301af351da7=287B, 1ec124b1-0c9c-6ad4-9d40-dfc04d23e0bc=287B})’.”
}
2.4.1.2. Выполнение SQL-запросов (асинхронный режим)
В асинхронном режиме получение результата осуществляется путем выполнения двух HTTP-запросов от ИС Потребителя к Агенту ПОДД СМЭВ:
В рамках первого HTTP-запроса (метод POST) передается SQL-запрос, в ответе возвращается идентификатор запроса.
В рамках второго HTTP-запроса (метод GET) передается ранее полученный идентификатор запроса, в ответе возвращается результат выполнения SQL-запроса.
Получение результата по указанному идентификатору возможно только один раз.
2.4.1.2.1. HTTP-запрос передачи SQL-запроса в Агент ПОДД (метод POST)
2.4.1.2.1.1. HTTP-запрос при подключении к Pulsar
№ |
Параметр |
Тип |
Обязательность |
Описание |
|---|---|---|---|---|
1 |
Тип запроса (Method) |
Да |
POST |
|
2 |
Путь (Path) |
Да |
<IP:port>/query |
|
header |
||||
1 |
Content-Type |
string |
Да |
application/x-www-form-urlencoded; charset=utf-8 |
2 |
Accept-version |
string |
Да |
Основная (major) часть версии (сейчас 1) |
3 |
ClientRequestID |
string |
Нет |
Клиентский идентификатор |
query |
||||
1 |
async |
boolean |
Нет |
Для синхронного режима выполнения запроса параметр должен отсутствовать или иметь значение False |
body |
||||
1 |
priority |
string |
Да |
Приоритет запроса. Варианты:
|
2 |
timeout |
string |
Нет |
|
3 |
sql |
string |
Да |
Текст SQL-запроса |
4 |
params |
array |
Нет |
Параметры запроса |
4.1 |
type |
string |
Да |
Тип параметра |
4.2 |
value |
string |
Да |
Значение параметра |
5 |
maxRows |
string |
Нет |
Максимальное количество возвращаемых записей таблицы ответа. Если не задан, возвращаются все записи. |
Пример запроса:
POST «https://10.81.4.30:29354/query?async=true»
Accept-Version:1
Content-Type:application/x-www-form-urlencoded; encoding=utf-8
priority:NORMAL
timeout:60
sql:SELECT ao.oktmo, o.name, o.kod from fias.addrobj ao LEFT JOIN oktmo.oktmo o on ao.oktmo = o.kod2 WHERE ao.offname= ? AND o.regionid = ?
params:{ “type”: “STRING”, “value”:”Москва”},{ “type”: “INTEGER”, “value”: “18”}
2.4.1.2.1.2. HTTP-запрос при подключении к брокеру
№ |
Параметр |
Тип |
Обязательность |
Описание |
|---|---|---|---|---|
1 |
Тип запроса (Method) |
Да |
POST |
|
2 |
Путь (Path) |
Да |
<IP:port>/regulated-query/async |
|
Заголовки |
||||
1 |
Content-Type |
string |
Да |
application/x-www-form-urlencoded; charset=utf-8 |
2 |
Accept-version |
string |
Да |
Основная (major) часть версии (сейчас 1) |
3 |
ClientRequestID |
string |
Нет |
Клиентский идентификатор |
Тело сообщения |
||||
1 |
priority |
string |
Да |
Приоритет запроса. Варианты:
|
2 |
timeout |
string |
Нет |
|
3 |
datamart |
string |
Нет |
Витрина Поставщика данных, к которой производится обращение |
4 |
mnemonic |
string |
Нет |
Мнемоника РЗ, к которому производится обращение |
5 |
majorVersion |
int |
Нет Если не указана majorVersion и minorVersion, обращение к актуальной версии |
Версия РЗ, к которому производится обращение |
6 |
majorVersion |
int |
Нет Если не указана majorVersion и minorVersion, обращение к актуальной версии Если не указана minorVersion и указанана majorVersion, обращение к последней версии в рамках majorVersion |
Версия РЗ, к которому производится обращение |
7 |
params |
array |
Нет |
Параметры запроса |
7.1 |
type |
string |
Да |
Тип параметра |
7.2 |
value |
string |
Да |
Значение параметра |
Пример запроса:
POST «https://10.81.4.30:29354/regulated-query/async»
Accept-Version:1
Content-Type:application/x-www-form-urlencoded; encoding=utf-8
priority:NORMAL
timeout:60
datamart: fias
mnemonic: addrobj_view
majorVersion: 1
minorVersion: 0
params:{ “type”: “STRING”, “value”:”Москва”},{ “type”: “INTEGER”, “value”: “18”}
2.4.1.2.1.3. Ответ на HTTP-запрос
Допустимые коды возврата:
201 – запрос создан;
400 – ошибка в запросе, информация об ошибке содержится в параметре «error»;
403 – нет полномочий на выполнение запроса, в том числе при блокировке полномочий на стороне Поставщика (с отображением соответствующего текста ошибки);
429 – ИС УВ временно заблокирована в связи с превышением лимитов;
503 – система временно недоступна, возможно повторить запрос через 50 мс.
№ |
Параметр |
Тип |
Обязательность |
Описание |
|---|---|---|---|---|
1 |
responseCode |
numeric |
Да |
Код возврата (HTTP-код) |
header |
||||
1 |
Content-Type |
string |
Да |
application/vnd.ru.rtlabs.podd.agent+json; version=1.0; charset=utf-8 |
2 |
Location |
string |
Да |
Временная ссылка на скачивание результата выполнения запроса |
3 |
ClientRequestID |
string |
Нет |
Клиентский идентификатор |
body |
||||
1 |
id |
string |
Да |
Уникальный идентификатор SQL-запроса |
2 |
deadline |
string |
Да |
Время, до которого доступен результат выполнения запроса |
Пример ответа с кодом возврата 201:
HTTP/1.1 201 Created
{
“id”: “a2f05175-d5bc-47d4-9b88-17930630683e”,
«deadline»: «2021-05-13T06:33:43Z»
}
Параметр |
Тип |
Обязательность |
Описание |
|---|---|---|---|
responseCode |
numeric |
Да |
Код возврата (HTTP-код) |
header |
|||
Content-Type |
string |
Да |
application/vnd.ru.rtlabs.podd.agent+json; version=1.0; charset=utf-8 |
body |
|||
error |
string |
Нет |
Текст ошибки |
2.4.1.2.2. HTTP-запрос получения результата, ранее переданного в Агент ПОДД СМЭВ асинхронного SQL-запроса (метод GET)
2.4.1.2.2.1. HTTP-запрос при подключении к Pulsar
Параметр |
Тип |
Обязательность |
Описание |
||||
|---|---|---|---|---|---|---|---|
Тип запроса (Method) |
Да |
GET |
|||||
Путь (Path) |
Да |
<IP:port>/query |
|||||
header |
|||||||
Accept |
string |
Да |
application/vnd.ru.rtlabs.podd.agent+json; charset=utf-8 |
||||
Accept-version |
string |
Да |
Основная (major) часть версии (сейчас 1) |
||||
ClientRequestID | string | Нет | Клиентский идентификатор |
|||||||
query |
|||||||
query_id |
string |
Да |
Уникальный идентификатор SQL-запроса |
||||
Пример запроса:
GET “https://10.81.4.30:29354/query/c005a0e7-0d26-4ce0-a1fa-10c8bdf4dfc5”
2.4.1.2.2.2. HTTP-запрос при подключении к брокеру
№ |
Параметр |
Тип |
Обязательность |
Описание |
|---|---|---|---|---|
1 |
Тип запроса (Method) |
Да |
GET |
|
2 |
Путь (Path) |
Да |
<IP:port>/regulated-query |
|
**Параметры |
||||
1 |
query_id |
string |
Да |
Уникальный идентификатор SQL-запроса |
Заголовки |
||||
1 |
Accept |
string |
Да |
application/vnd.ru.rtlabs.podd.agent+json; charset=utf-8 |
2 |
Accept-version |
string |
Да |
Основная (major) часть версии (сейчас 1) |
3 |
ClientRequestID |
string |
Нет |
Клиентский идентификатор |
Пример запроса:
GET “https://10.81.4.30:29354/ regulated-query/c005a0e7-0d26-4ce0-a1fa-10c8bdf4dfc5”
2.4.1.2.2.3. Ответ на HTTP-запрос
Допустимые коды возврата:
503 – система временно недоступна, возможно повторить запрос через 50 мс;
500 – системная ошибка (в связи в принятыми ограничениями по доступности код 500 предполагается только при сбое Агента);
429 – ИС УВ временно заблокирована в связи с превышением лимитов;
406 – неподдерживаемая версия протокола (после внедрения поддержки обратной совместимости возвращается только для несуществующих версий);
404 – Результат по заданному идентификатору SQL-запроса не найден;
403 – нет полномочий на выполнение запроса, в том числе при блокировке полномочий на стороне Поставщика (с отображением соответствующего текста ошибки);
400 – ошибка в запросе, информация об ошибке содержится в параметре «error»;
202 – результат по заданному идентификатору SQL-запроса еще не поступил;
200 – ок.
№ |
Параметр |
Тип |
Обязательность |
Описание |
|---|---|---|---|---|
1 |
responseCode |
numeric |
Да |
Код возврата (HTTP-код) |
header |
||||
1 |
Content-Type |
string |
Да |
application/vnd.ru.rtlabs.podd.agent+json; version=1.0; charset=utf-8 |
2 |
ClientRequestID |
string |
Нет |
Клиентский идентификатор |
body |
||||
1 |
created_at |
dateTime |
Да |
Время формирования ответа. Время, с которого ответ доступен для получения по запросу |
2 |
query_id |
string |
Да |
Идентификатор запроса |
3 |
rows |
array |
Нет |
Массив записей таблицы ответа (в случае если результат выполнения запроса в виде таблицы). При задании параметра «maxRows» ограничивается его значением |
3.1 |
array |
Да |
Массив значений. Возможным значением может быть содержимое файла, закодированное в формате BASE64 |
|
4 |
meta |
array |
Да |
Список полей результата |
4.1 |
name |
string |
Да |
Имя поля |
4.2 |
type |
string |
Да |
Тип поля |
Пример ответа с кодом возврата 200:
HTTP/1.1 200 OK
{
“created_at”: “2017-12-15T07:36:03Z”,
“query_id”: “c005a0e7-0d26-4ce0-a1fa-10c8bdf4dfc5”,
“meta”: [
{
“name”: “count”,
“type”: “INTEGER”
}
],
«rows»: [
[
«4994»
]
]
}
№ |
Параметр |
Тип |
Обязательность |
Описание |
|---|---|---|---|---|
1 |
responseCode |
numeric |
Да |
Код возврата (HTTP-код) |
header |
||||
1 |
Content-Type |
string |
Да |
application/vnd.ru.rtlabs.podd.agent+json; version=1.0; charset=utf-8 |
2 |
ClientRequestID |
string |
Нет |
Клиентский идентификатор |
body |
||||
1 |
query_id |
string |
Нет |
Идентификатор запроса |
2 |
created_at |
dateTime |
Нет |
Время формирования ответа – время, с которого ответ доступен для получения по запросу |
3 |
error |
string |
Нет |
Текст ошибки |
2.4.1.3. Выполнение запроса с табличным параметром
Может быть выполнен как в синхронном, так и в асинхронном режиме. Ответ соответствует способу вызова.
2.4.1.3.1. HTTP-запрос с табличным параметром при подключении к Pulsar
№ |
Параметр |
Тип |
Обязательность |
Описание |
|---|---|---|---|---|
1 |
Тип запроса (Method) |
Да |
POST |
|
2 |
Путь (Path) |
Да |
<IP:port>/query |
|
query |
||||
1 |
async |
boolean |
Нет |
Для синхронного режима выполнения запроса параметр должен отсутствовать или иметь значение False Для асинхронного режима выполнения запроса параметр должен иметь значение True |
header |
||||
1 |
Content-Type |
string |
Да |
multipart/form-data; |
2 |
Connection |
string |
Да |
keep-alive |
3 |
Keep-Alive: |
string |
Да |
300 |
4 |
ClientRequestID |
string |
Нет |
Клиентский идентификатор |
boundary |
||||
1 |
Content-Disposition |
application/json name=request |
||
2 |
Content-Type |
string |
Да |
application/json; charset=utf-8 |
3 |
Accept-version |
string |
Да |
Основная (major) часть версии (сейчас 1) |
json |
||||
1 |
priority |
string |
Да |
Приоритет запроса. Варианты:
|
2 |
timeout |
string |
Нет |
Предельное время ожидания выполнения запроса в секундах Запросы без указания данного параметра использовать не рекомендуется, следует указать значение, равное времени ожидания ответа на ИС Потребителя (максимум 90 дней) В случае отсутствия параметра в запросе таймаут имеет значение по умолчанию 1 час |
3 |
sql |
string |
Да |
Текст SQL-запроса |
4 |
tableParams |
array |
Да |
Описание передаваемого файла с данными для табличного параметра |
4.1 |
name |
string |
Да |
Наименование табличного параметра, соответствующее
указанному в SQL-выражении в формате |
4.2 |
columns |
array |
Да |
Перечень наименований столбцов и их типов, содержащихся в файле с данными для табличного параметра |
4.2.1 |
name |
string |
Да |
Наименование столбца |
4.2.2 |
type |
string |
Да |
Тип столбца |
5 |
<name> |
Да |
Файл с данными для табличного параметра. Имя параметра соответствует наименованию табличного параметра |
|
file |
||||
5.1 |
файл в формате CSV |
Да |
Файл в формате CSV (поддерживаемый формат), передаваемый в параметре запроса |
|
boundary |
||||
1 |
Content-Disposition |
string |
Да |
form-data; name=”table1”; filename=”table1.csv” |
Пример запроса приведен в Раздел 3.1.1.1 настоящего документа.
2.4.1.3.2. HTTP-запрос с табличным параметром при подключении к брокеру
№ |
Параметр |
Тип |
Обязательность |
Описание |
|---|---|---|---|---|
1 |
Тип запроса (Method) |
Да |
POST |
|
2 |
Путь (Path) |
Да |
<IP:port>/regulated-query – для синхронного вызова <IP:port>/regulated-query/async – для асинхронного вызова |
|
Заголовки |
||||
1 |
Content-Type |
string |
Да |
multipart/form-data; |
2 |
Connection |
string |
Да |
keep-alive |
3 |
Accept-version |
string |
Да |
Основная (major) часть версии (сейчас 1) |
4 |
ClientRequestID |
string |
Нет |
Клиентский идентификатор |