.. _connection_description: Описание подключения к ПОДД СМЭВ ================================== .. _participants_connect: Подключение участников взаимодействия с использованием ПОДД СМЭВ ---------------------------------------------------------------- Основным способом направления обращений является использование Личного кабинета СЦ https://sc.minsvyaz.ru. Электронная почта `sd@sc.minsvyaz.ru `_ является резервным способом направления обращений, который используется в случае недоступности Личного кабинета СЦ. Более подробная информация о порядке подключения к СМЭВ 4 приведена в документе «Регламент подключения к СМЭВ 4» [18]_. .. _provider_protocol: Протокол взаимодействия Агента ПОДД СМЭВ и Витрины Поставщика данных ----------------------------------------------------------------------- Агент ПОДД СМЭВ Поставщика данных может взаимодействовать с несколькими Витринами данных. Протокол коммуникации Агента и Витрин реализован в виде обмена сообщениями с использованием зарезервированных топиков брокера сообщений Apache Kafka. .. _provider_kafka_topics: Перечень топиков брокера сообщений Apache Kafka ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Конфигурация Агента содержит перечень Витрин данных, с которыми он взаимодействует. Каждой Витрине в зависимости от настроек конфигурации, заданных в соответствии с «Руководством администратора ПОДД СМЭВ»[19]_ соответствует один из наборов топиков: 1. Набор топиков, создаваемый по умолчанию. Полное название топиков формируются по шаблону ``<префикс для динамически регистрируемых Витрин>.<название топика>``. По умолчанию префикс отсутствует. 2. Дополнительный набор топиков. Полное название топиков формируются по следующему шаблону ``<префикс для статически регистрируемых Витрин>.<название топика>``. По умолчанию создаются отдельные группы топиков для каждой схемы Витрины с префиксом, соответствующим мнемонике Витрины. Названия топиков брокера сообщений [20]_ приведены в :numref:`tab_broker_topics_name`. .. _tab_broker_topics_name: .. table:: Названия топиков брокера сообщений Apache Kafka +----+---------------------------------+-------------+------------------+----------------------------------------------------+ | № | Топик | Публикатор | Подписчик | Передаваемый объект | +====+=================================+=============+==================+====================================================+ | *Топики регистрации и настройки Витрин* | +----+---------------------------------+-------------+------------------+----------------------------------------------------+ | 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 | Витрина | Агент | События Витрины для дальнейшей передачи в СЦЛ | +----+---------------------------------+-------------+------------------+----------------------------------------------------+ | *Топики для временного хранения сообщений при недоступности ПОДД* | +----+---------------------------------+-------------+------------------+----------------------------------------------------+ | 33 | <идентификатор ядра ПОДД>. | Агент | Агент | Сообщения от Витрины для передачи в ПОДД | | | <мнемоника агента>.undelivered. | | | | | | message | | | | +----+---------------------------------+-------------+------------------+----------------------------------------------------+ .. [18] Регламент подключения к СМЭВ 4 размещен на портале ЕСКС – https://info.gosuslugi.ru/ .. [19] Документ размещен на портале ЕСКС – https://info.gosuslugi.ru/ .. [20] Далее в :numref:`consumer_protocol` префикс <префикс> в названии топиков может быть опущен. .. _provider_several_datamarts_settings: Настройка Агента ПОДД для работы с несколькими Витринами данных ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ В ПОДД предусмотрено два способа регистрации Витрин данных: - на основе сообщений от Витрин; - на основе конфигурационного файла. Регистрация Витрины осуществляется вне зависимости от наличия загруженных в ПОДД метаданных Витрин (:numref:`provider_model_data`). Выполнение запросов к Витринам возможно только после успешной регистрации Витрины и получения метаданных в ПОДД СМЭВ. .. _provider_config_register: Регистрация на основе конфигурационного файла ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Поддерживается на стороне Потребителя и Поставщика. :numref:`tab_provider_config_register` содержит описание процесса регистрации Витрины. .. _tab_provider_config_register: .. table:: Процесс регистрации Витрины данных +--------------------------------------------+-----+--------------------------------------------------------------+ | Процесс | Шаг | Описание | +============================================+=====+==============================================================+ | **Инициация регистрации** | 1 | При запуске Агент вычитывает локальный конфигурационный | | | | файл [21]_ с настройками регистрации Витрин. Витрина может | | | | быть зарегистрирована: | | | | | | | | - статически (при явном указании в конфигурационном файле) | | | | | | | | - динамически (автоматическая регистрация Витрины при | | | | обращению к/от Витрины, без необходимости указания в | | | | конфигурационном файле) | | | | | | | | и создает согласно настройкам в конфигурационном файле: | | | | | | | | - группу топиков по умолчанию (для динамически | | | | регистрируемых Витрин) | | | | | | | | - одну или несколько дополнительных групп топиков (для | | | | статически регистрируемых Витрин) | | +-----+--------------------------------------------------------------+ | | 2 | Если одному из Агентов приходит сообщение из Ядра для | | | | незарегистрированной Витрины, Агент регистрирует её | | | | динамически (и при необходимости создает группу топиков по | | | | умолчанию). | | +-----+--------------------------------------------------------------+ | | 3 | Если инициатором сообщения будет Витрина или ИС Потребителя, | | | | они будут зарегистрированы динамически, если при старте | | | | Агента создана группа топиков по умолчанию. | +--------------------------------------------+-----+--------------------------------------------------------------+ | **Регистрация** | 4 | Агент загружает профиль Витрины. Способ загрузки | | | | определяется значением registrationFlow в конфигурационном | | | | файле: | | | | | | | | - DEFINED_PROFILE – загрузка по указанному в конфигурации | | | | пути (по умолчанию); | | | | | | | | - DATAMART_REQUEST – запрос к Витрине через топик | | | | <префикс>.profile.rq | | +-----+--------------------------------------------------------------+ | | 5 | Витрина данных передаёт: | | | | | | | | - либо профиль Витрины через топик <префикс>.profile.rs | | | | | | | | - либо сообщение об ошибке в топик <префикс>.profile.err | | +-----+--------------------------------------------------------------+ | | 6 | Агент, получивший запрос от Витрины: | | | | | | | | - уведомляет Ядро ПОДД СМЭВ о регистрации профиля новой | | | | Витрины, | | | | | | | | - передаёт в Ядро ПОДД СМЭВ профиль Витрины | | | | | | | | - ожидает подтверждения регистрации от Ядра ПОДД | | +-----+--------------------------------------------------------------+ | | 7 | Ядро ПОДД: осуществляет регистрацию | | +-----+--------------------------------------------------------------+ | | 8 | Направляет в Агент подтверждение регистрации Витрины. | | | | | | | | При успешном выполнении всех регистрационных операций, либо | | | | если данная Витрина уже зарегистрирована возвращается статус | | | | «успех», в противном случае «не успех». | +--------------------------------------------+-----+--------------------------------------------------------------+ | **Действия после успешной Регистрации** | 9 | Агент (при запуске) вычитывает метаданные Витрин из Ядра | | | | ПОДД через специальный топик. | | | | | | | | Чтение метаданных не препятствует запуску, то есть в | | | | процессе чтения Агент уже может принимать запросы. | | | | | | | | Обновление метаданных производится при каждом перезапуске | | | | Агента | +--------------------------------------------+-----+--------------------------------------------------------------+ | **Действия после не успешной Регистрации** | 10 | Агент завершает работу с ошибкой | +--------------------------------------------+-----+--------------------------------------------------------------+ .. [21] Описание приведено в Руководстве администратора Агента ПОДД СМЭВ, размещенном на портале ЕСКС – https://info.gosuslugi.ru/ .. _provider_datamart_register: Регистрация на основе сообщений Витрин ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Только для Поставщика. :numref:`tab_provider_datamart_register` содержит описание процесса регистрации Витрины, схема регистрации на основе сообщения от Витрины приведена на :numref:`img_provider_datamart_register`. .. _tab_provider_datamart_register: .. table:: Процесс регистрации Витрины данных +-------------------------------------------+-----+------------------------------------------------------------------+ | Процесс | Шаг | Описание | +===========================================+=====+==================================================================+ | **Инициация регистрации** | 1 | Витрина данных направляет в Агент сообщение с | | | | регистрационными данными в общий топик Kafka ``datamart.signal`` | | | | предназначенный для получения запросов на регистрацию от | | | | всех Витрин. Структура сообщения приведена в :ref:`annex_2` | | | | | | | | При отправке запроса на регистрацию Витрина должна обеспечить | | | | подписку на топик ``signal`` | +-------------------------------------------+-----+------------------------------------------------------------------+ | **Регистрация** | 2 | Агент создаёт необходимые для работы с новой Витриной данных | | | | топики в соответствии с :numref:`tab_broker_topics_name`. | | +-----+------------------------------------------------------------------+ | | 3 | Агент запрашивает у Витрины профиль через топик ``profile.rq``. | | +-----+------------------------------------------------------------------+ | | 4 | Агент получает: | | | | | | | | - либо профиль Витрины через топик ``profile.rs`` | | | | | | | | - либо сообщение об ошибке в топик ``profile.err`` | | +-----+------------------------------------------------------------------+ | | 5 | Агент: | | | | | | | | - уведомляет Ядро ПОДД СМЭВ о регистрации профиля новой Витрины, | | | | | | | | - передаёт в Ядро ПОДД СМЭВ профиль Витрины, | | | | | | | | - ожидает подтверждения регистрации от Ядра ПОДД. | | +-----+------------------------------------------------------------------+ | | 6 | Агент получает подтверждение регистрации профиля Витрины от Ядра | | | | ПОДД СМЭВ. | | | | | | | | При успешном выполнении всех регистрационных операций, либо если | | | | данная Витрина уже зарегистрирована возвращается статус «успех», | | | | в противном случае «не успех». | | +-----+------------------------------------------------------------------+ | | 7 | Агент направляет Витрине сообщение о статусе регистрации. | | +-----+------------------------------------------------------------------+ | | 8 | В случае неуспешной регистрации Агент удаляет созданные на шаге | | | | 2 топики в Kafka. | +-------------------------------------------+-----+------------------------------------------------------------------+ | **Действия после успешной Регистрации** | 9 | Агент выполняет запрос к Ядру ПОДД СМЭВ за актуальной | | | | информацией о зарегистрированных Витринах (метаданные Витрины и | | | | иные данные, необходимые для корректной работы) [22]_ и | | | | обновляет по полученным данным хранимую локально сводную | | | | информацию. | | | | | | | | Агент завершает процедуру запуска только после получения | | | | актуальных данных. | +-------------------------------------------+-----+------------------------------------------------------------------+ | **Действия после неуспешной Регистрации** | 10 | В случае ошибок, таймаутов и сбоев, инициация повторной | | | | регистрации обеспечивается Витриной. | +-------------------------------------------+-----+------------------------------------------------------------------+ .. [22] Данная информация используется Агентом при работе и обновляется на основе актуальных данных от Ядра при каждом перезапуске. .. _img_provider_datamart_register: .. figure:: img/provider_datamart_register.png :align: center :alt: Процесс регистрации Витрины данных на основе сообщения от Витрины данных Процесс регистрации Витрины данных на основе сообщения от Витрины данных .. _provider_realisation_example: Примеры реализации взаимодействия с Агентом ПОДД СМЭВ с использованием брокера сообщений Apache Kafka ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Далее приведены примеры программного кода, реализующие следующие процедуры с использованием брокера сообщений Apache Kafka: - получение запроса от Агента ПОДД СМЭВ; - передача результата Агенту ПОДД СМЭВ. Пример проекта для реализации взаимодействия с Агентом приведен в :ref:`annex_1`. .. _provider_get_request: Получение запроса от Агента ПОДД СМЭВ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Пример программного кода для получения запроса от Агента ПОДД СМЭВ с использованием брокера сообщений Apache Kafka: .. code-block:: 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(kafkaProperties) val topicProperties = loadProperties("/topic.properties") val handlers = mapOf( queryRequestHandler(topicProperties, producer), ) KafkaConsumer(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) = 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) { logger.error { "Не сконфигурирован обработчик для топика $topic" } } companion object : KLogging() } .. _provider_send_response: Передача результата Агенту ПОДД СМЭВ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Пример программного кода для передачи результата выполнения запрос Агенту ПОДД СМЭВ с использованием брокера сообщений Apache Kafka: .. code-block:: 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, 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) { 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) { 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) { 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, subRequestId: UUID) { tableParams.forEach { tableParamStorage.wait(subRequestId, it) } } private suspend fun deleteAllParameters(tableParams: List, 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> = 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, 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 ?: "" ) } .. _consumer_protocol: Протокол взаимодействия Агента ПОДД СМЭВ и ИС Потребителя данных ----------------------------------------------------------------------- Для обеспечения доступности данных Агент ПОДД СМЭВ предоставляет: - REST-интерфейс для выполнения запросов к Витринам Поставщиков данных (:numref:`consumer_sql_rest_interface` данного документа); - REST-интерфейс для выполнения запросов к REST-сервису ИС Ответчика (:numref:`respondent_rest_interface` документа). - специализированный протокол для исполнения запросов к Витринам Поставщиков данных с использованием JDBC-интерфейса Агента ПОДД (:numref:`jdbc_interface` данного документа). .. _consumer_sql_rest_interface: REST-интерфейс Агента ПОДД для SQL-запросов ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ В Агенте ПОДД СМЭВ реализована поддержка REST-интерфейса для выполнения запросов к Витринам Поставщиков данных. URL-адрес для выполнения обращений к REST-интерфейсу имеет следующий формат: ``http://<адрес>:<порт>/query``, где: - ``<адрес>`` – IP-адрес Агента ПОДД СМЭВ; - ``<порт>`` – порт, на котором развернут REST-интерфейс в соответствии с «Руководством администратора ПОДД СМЭВ» [23]_. Входные параметры, включая текст SQL-запроса (в случае обращения к Витринам Поставщиков данных), должны кодироваться в виде JSON-строки и передаваться в теле запроса. Результат выполнения SQL-запроса передается в теле HTTP-ответа в виде JSON-строки. Файлы, передаваемые в составе результата выполнения SQL-запроса, включаются в JSON как строковые атрибуты, кодирующие содержимое передаваемого файла с использованием Base64. Файлы в составе результата выполнения запроса BLOB по ссылке передаются в виде массива байт. Возможно выполнение запросов к Витринам Поставщиков данных: - в синхронном режиме (см. :numref:`consumer_sql_sync_request`); - в асинхронном режиме (см. :numref:`consumer_sql_async_request`); - на получение BLOB по ссылке (см. :numref:`consumer_tp_request`). .. [23] Размещен на портале ЕСКС – https://info.gosuslugi.ru/ .. _consumer_sql_sync_request: Выполнение SQL-запросов (синхронный режим) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ В синхронном режиме получение результата осуществляется путем выполнения HTTP-запроса от ИС Потребителя к Агенту ПОДД. В рамках HTTP-запроса (метод POST) передается SQL-запрос, в ответе возвращается результат выполнения SQL-запроса. .. _sync_pulsar_connect: HTTP-запрос ############# .. table:: HTTP-запрос +-----+----------------------+---------+----------------+--------------------------------------------------+ | № | Параметр | Тип | Обязательность | Описание | +=====+======================+=========+================+==================================================+ | 1 | Тип запроса (Method) | - | Да | POST | +-----+----------------------+---------+----------------+--------------------------------------------------+ | 2 | Путь (Path) | - | Да | /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 | Да | Приоритет запроса. Варианты: | | | | | | | | | | | | - NORMAL; | | | | | | | | | | | | - HIGH | +-----+----------------------+---------+----------------+--------------------------------------------------+ | 2 | timeout | string | Нет | Предельное время ожидания выполнения запроса. | | | | | | | | | | | | Запросы без указания данного параметра | | | | | | использовать не рекомендуется, следует указать | | | | | | значение, равное времени ожидания ответа на ИС | | | | | | Потребителя. Максимальное значение 24 часа | | | | | | | | | | | |В случае отсутствия параметра в запросе таймаут | | | | | | имеет значение по умолчанию 1 час | +-----+----------------------+---------+----------------+--------------------------------------------------+ | 3 | sql | string | Да | Текст SQL-запроса к Витринам Поставщиков данных | +-----+----------------------+---------+----------------+--------------------------------------------------+ | 4 | params | array | Нет | Параметры запроса | +-----+----------------------+---------+----------------+--------------------------------------------------+ | 4.1 | type | string | Да | Тип параметра | +-----+----------------------+---------+----------------+--------------------------------------------------+ | 4.2 | value | string | Да | Значение параметра | +-----+----------------------+---------+----------------+--------------------------------------------------+ | 5 | maxRows | string | Нет | Максимальное количество возвращаемых записей | | | | | | таблицы ответа. Если не задан, возвращаются все | | | | | | записи. | +-----+----------------------+---------+----------------+--------------------------------------------------+ Пример запроса: .. code-block:: 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”} .. _sync_broker_connect: HTTP-запрос на вызов Регламентированного SQL-запроса без надстроек ##################################################################### .. table:: HTTP-запрос на вызов Регламентированного SQL-запроса без надстроек +-----+----------------------+---------+-------------------------------+--------------------------------------------------+ | № | Параметр | Тип | Обязательность | Описание | +=====+======================+=========+===============================+==================================================+ | 1 | Тип запроса (Method) | - | Да | POST | +-----+----------------------+---------+-------------------------------+--------------------------------------------------+ | 2 | Путь (Path) | - | Да | /regulated-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 | Да | Приоритет запроса. Варианты: | | | | | | | | | | | | - NORMAL; | | | | | | | | | | | | - HIGH | +-----+----------------------+---------+-------------------------------+--------------------------------------------------+ | 2 | timeout | string | Нет | Предельное время ожидания выполнения запроса. | | | | | | | | | | | | Запросы без указания данного параметра | | | | | | использовать не рекомендуется, следует указать | | | | | | значение, равное времени ожидания ответа на ИС | | | | | | Потребителя. Максимальное значение 24 часа | | | | | | | | | | | |В случае отсутствия параметра в запросе таймаут | | | | | | имеет значение по умолчанию 1 час | +-----+----------------------+---------+-------------------------------+--------------------------------------------------+ | 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 | Да | Значение параметра | +-----+----------------------+---------+-------------------------------+--------------------------------------------------+ Пример запроса: .. code-block:: 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 .. _sync_response: Ответ на HTTP-запрос ######################## Допустимые коды возврата: - 200 – ок; - 400 – ошибка в запросе, информация об ошибке содержится в параметре «error»; - 403 – нет полномочий на выполнение запроса, в том числе при блокировке полномочий на стороне Поставщика (с отображением соответствующего текста ошибки); - 406 – неподдерживаемая версия протокола (после внедрения поддержки обратной совместимости возвращается только для несуществующих версий); - 429 – ИС УВ временно заблокирована в связи с превышением лимитов; - 500 – системная ошибка (в связи в принятыми ограничениями по доступности код 500 предполагается только при сбое Агента); - 503 – система временно недоступна, возможно повторить запрос через 50 мс. .. table:: Параметры ответа с кодом возврата 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: .. code-block:: 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: .. code-block:: 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" ] ] } .. table:: Параметры ответа с кодом возврата, отличным от 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 | error | string | Нет | Текст ошибки | +-----+----------------------+----------+----------------+--------------------------------------------------+ Пример ответа с кодом возврата, отличным от 200: .. code-block:: 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})’.” } .. _consumer_sql_async_request: Выполнение SQL-запросов (асинхронный режим) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ В асинхронном режиме получение результата осуществляется путем выполнения двух HTTP-запросов от ИС Потребителя к Агенту ПОДД СМЭВ: 1. В рамках первого HTTP-запроса (метод POST) передается SQL-запрос, в ответе возвращается идентификатор запроса. 2. В рамках второго HTTP-запроса (метод GET) передается ранее полученный идентификатор запроса, в ответе возвращается результат выполнения SQL-запроса. Получение результата по указанному идентификатору возможно только один раз. .. _consumer_async_sql_post_request: HTTP-запрос передачи SQL-запроса в Агент ПОДД (метод POST) ############################################################## .. _async_post_pulsar_connect: HTTP-запрос на вызов запроса с надстройками ************************************************* .. table:: HTTP-запрос на вызов запроса с надстройками +-----+----------------------+---------+----------------+--------------------------------------------------+ | № | Параметр | Тип | Обязательность | Описание | +=====+======================+=========+================+==================================================+ | 1 | Тип запроса (Method) | - | Да | POST | +-----+----------------------+---------+----------------+--------------------------------------------------+ | 2 | Путь (Path) | - | Да | /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 | Нет | Для асинхронного режима выполнения запроса | | | | | | параметр должен отсутствовать или иметь значение | | | | | | True | +-----+----------------------+---------+----------------+--------------------------------------------------+ | **body** | +-----+----------------------+---------+----------------+--------------------------------------------------+ | 1 | priority | string | Да | Приоритет запроса. Варианты: | | | | | | | | | | | | - NORMAL; | | | | | | | | | | | | - HIGH | +-----+----------------------+---------+----------------+--------------------------------------------------+ | 2 | timeout | string | Нет | Предельное время ожидания выполнения запроса. | | | | | | | | | | | | Запросы без указания данного параметра | | | | | | использовать не рекомендуется, следует указать | | | | | | значение, равное времени ожидания ответа на ИС | | | | | | Потребителя. Максимальное значение 24 часа | | | | | | | | | | | |В случае отсутствия параметра в запросе таймаут | | | | | | имеет значение по умолчанию 1 час | +-----+----------------------+---------+----------------+--------------------------------------------------+ | 3 | sql | string | Да | Текст SQL-запроса | +-----+----------------------+---------+----------------+--------------------------------------------------+ | 4 | params | array | Нет | Параметры запроса | +-----+----------------------+---------+----------------+--------------------------------------------------+ | 4.1 | type | string | Да | Тип параметра | +-----+----------------------+---------+----------------+--------------------------------------------------+ | 4.2 | value | string | Да | Значение параметра | +-----+----------------------+---------+----------------+--------------------------------------------------+ | 5 | maxRows | string | Нет | Максимальное количество возвращаемых записей | | | | | | таблицы ответа. Если не задан, возвращаются все | | | | | | записи. | +-----+----------------------+---------+----------------+--------------------------------------------------+ Пример запроса: .. code-block:: 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”} .. _async_post_broker_connect: HTTP-запрос на вызов запроса без надстроек ******************************************** .. table:: HTTP-запрос на вызов запроса без надстроек +-----+----------------------+---------+-------------------------------+--------------------------------------------------+ | № | Параметр | Тип | Обязательность | Описание | +=====+======================+=========+===============================+==================================================+ | 1 | Тип запроса (Method) | - | Да | POST | +-----+----------------------+---------+-------------------------------+--------------------------------------------------+ | 2 | Путь (Path) | - | Да | /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 | Да | Приоритет запроса. Варианты: | | | | | | | | | | | | - NORMAL; | | | | | | | | | | | | - HIGH | +-----+----------------------+---------+-------------------------------+--------------------------------------------------+ | 2 | timeout | string | Нет | Предельное время ожидания выполнения запроса. | | | | | | | | | | | | Запросы без указания данного параметра | | | | | | использовать не рекомендуется, следует указать | | | | | | значение, равное времени ожидания ответа на ИС | | | | | | Потребителя. Максимальное значение 24 часа | | | | | | | | | | | |В случае отсутствия параметра в запросе таймаут | | | | | | имеет значение по умолчанию 1 час | +-----+----------------------+---------+-------------------------------+--------------------------------------------------+ | 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 | Да | Значение параметра | +-----+----------------------+---------+-------------------------------+--------------------------------------------------+ Пример запроса: .. code-block:: 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”} .. _async_post_response: Ответ на HTTP-запрос ******************** Допустимые коды возврата: - 201 – запрос создан; - 400 – ошибка в запросе, информация об ошибке содержится в параметре «error»; - 403 – нет полномочий на выполнение запроса, в том числе при блокировке полномочий на стороне Поставщика (с отображением соответствующего текста ошибки); - 429 – ИС УВ временно заблокирована в связи с превышением лимитов; - 503 – система временно недоступна, возможно повторить запрос через 50 мс. .. table:: Параметры ответа с кодом возврата 201: +-----+----------------------+----------+----------------+--------------------------------------------------+ | № | Параметр | Тип | Обязательность | Описание | +=====+======================+==========+================+==================================================+ | 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 | Да | Время, до которого доступен результат выполнения | | | | | | запроса. Время хранения результата составляет 24 | | | | | | часа | +-----+----------------------+----------+----------------+--------------------------------------------------+ Пример ответа с кодом возврата 201: .. code-block:: HTTP/1.1 201 Created { “id”: “a2f05175-d5bc-47d4-9b88-17930630683e”, «deadline»: «2021-05-13T06:33:43Z» } .. table:: Параметры ответа с кодом возврата 400: +----------------------+----------+----------------+--------------------------------------------------+ | Параметр | Тип | Обязательность | Описание | +======================+==========+================+==================================================+ | responseCode | numeric | Да | Код возврата (HTTP-код) | +----------------------+----------+----------------+--------------------------------------------------+ | **header** | +----------------------+----------+----------------+--------------------------------------------------+ | Content-Type | string | Да | application/vnd.ru.rtlabs.podd.agent+json; | | | | | version=1.0; charset=utf-8 | +----------------------+----------+----------------+--------------------------------------------------+ | **body** | +----------------------+----------+----------------+--------------------------------------------------+ | error | string | Нет | Текст ошибки | +----------------------+----------+----------------+--------------------------------------------------+ .. _consumer_async_sql_get_response: HTTP-запрос получения результата, ранее переданного в Агент ПОДД СМЭВ асинхронного SQL-запроса (метод GET) ############################################################################################################ .. _async_get_pulsar_connect: HTTP-запрос при вызове исходного запроса с надстройками ************************************************************* .. table:: HTTP-запрос при вызове исходного запроса с надстройками +----------------------+---------+----------------+----------------------------------------------------------+ | Параметр | Тип | Обязательность | Описание | +======================+=========+================+==========================================================+ | Тип запроса (Method) | - | Да | GET | +----------------------+---------+----------------+----------------------------------------------------------+ | Путь (Path) | - | Да | /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-запроса | +----------------------+---------+----------------+----------------------------------------------------------+ Пример запроса: .. code-block:: GET “https://10.81.4.30:29354/query/c005a0e7-0d26-4ce0-a1fa-10c8bdf4dfc5” .. _async_get_broker_connect: HTTP-запрос при вызове исходного запроса без надстроек ********************************************************* .. table:: HTTP-запрос при вызове исходного запроса без надстроек +-----+----------------------+---------+----------------+----------------------------------------------------------+ | № | Параметр | Тип | Обязательность | Описание | +=====+======================+=========+================+==========================================================+ | 1 | Тип запроса (Method) | - | Да | GET | +-----+----------------------+---------+----------------+----------------------------------------------------------+ | 2 | Путь (Path) | - | Да | /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 | Нет | Клиентский идентификатор | +-----+----------------------+---------+----------------+----------------------------------------------------------+ Пример запроса: .. code-block:: GET “https://10.81.4.30:29354/ regulated-query/c005a0e7-0d26-4ce0-a1fa-10c8bdf4dfc5” .. _async_get_response: Ответ на HTTP-запрос ************************ Допустимые коды возврата: - 503 – система временно недоступна, возможно повторить запрос через 50 мс; - 500 – системная ошибка (в связи в принятыми ограничениями по доступности код 500 предполагается только при сбое Агента); - 429 – ИС УВ временно заблокирована в связи с превышением лимитов; - 406 – неподдерживаемая версия протокола (после внедрения поддержки обратной совместимости возвращается только для несуществующих версий); - 404 – Результат по заданному идентификатору SQL-запроса не найден; - 403 – нет полномочий на выполнение запроса, в том числе при блокировке полномочий на стороне Поставщика (с отображением соответствующего текста ошибки); - 400 – ошибка в запросе, информация об ошибке содержится в параметре «error»; - 202 – результат по заданному идентификатору SQL-запроса еще не поступил; - 200 – ок. .. table:: Параметры ответа с кодом возврата 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: .. code-block:: 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» ] ] } .. table:: Параметры ответа с кодом возврата, отличным от 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 | query_id | string | Нет | Идентификатор запроса | +----+----------------------+----------+----------------+--------------------------------------------------+ | 2 | created_at | dateTime | Нет | Время формирования ответа – время, с которого | | | | | | ответ доступен для получения по запросу | +----+----------------------+----------+----------------+--------------------------------------------------+ | 3 | error | string | Нет | Текст ошибки | +----+----------------------+----------+----------------+--------------------------------------------------+ .. _consumer_tp_request: Выполнение запроса с табличным параметром ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Может быть выполнен как в синхронном, так и в асинхронном режиме. Ответ соответствует способу вызова. .. _tp_pulsar_connect: HTTP-запрос с табличным параметром на вызов запроса с надстройками #################################################################### .. table:: HTTP-запрос с табличным параметром на вызов запроса с надстройками +-------+----------------------+----------+----------------+----------------------------------------------------------+ | № | Параметр | Тип | Обязательность | Описание | +=======+======================+==========+================+==========================================================+ | 1 | Тип запроса (Method) | - | Да | POST | +-------+----------------------+----------+----------------+----------------------------------------------------------+ | 2 | Путь (Path) | - | Да | /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 | Да | Приоритет запроса. Варианты: | | | | | | | | | | | | - NORMAL; | | | | | | | | | | | | - HIGH | +-------+----------------------+----------+----------------+----------------------------------------------------------+ | 2 | timeout | string | Нет | Предельное время ожидания выполнения запроса в секундах | | | | | | | | | | | | В случае отсутствия параметра в запросе таймаут не | | | | | | выставляется | +-------+----------------------+----------+----------------+----------------------------------------------------------+ | 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 | | | Да | Файл с данными для табличного параметра. Имя параметра | | | | | | соответствует наименованию табличного параметра | +-------+----------------------+----------+----------------+----------------------------------------------------------+ | **file** | +-------+----------------------+----------+----------------+----------------------------------------------------------+ | 5.1 | - | файл в | Да | Файл в формате CSV (поддерживаемый формат), передаваемый | | | | формате | | в параметре запроса | | | | CSV | | | +-------+----------------------+----------+----------------+----------------------------------------------------------+ | **boundary** | +-------+----------------------+----------+----------------+----------------------------------------------------------+ | 1 | Content-Disposition | string | Да | form-data; name=”table1”; filename=”table1.csv” | +-------+----------------------+----------+----------------+----------------------------------------------------------+ Пример запроса приведен в :numref:`rest_interface_request` настоящего документа. .. _tp_broker_connect: HTTP-запрос с табличным параметром на вызов запроса без надстроек #################################################################### .. table:: HTTP-запрос с табличным параметром на вызов запроса без надстроек +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ | № | Параметр | Тип | Обязательность | Описание | +=======+======================+=========+===============================+==================================================+ | 1 | Тип запроса (Method) | - | Да | POST | +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ | 2 | Путь (Path) | - | Да | /regulated-query – для синхронного | | | | | | вызова | | | | | | | | | | | | /regulated-query/async – для | | | | | | асинхронного вызова | +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ | **Заголовки** | +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ | 1 | Content-Type | string | Да | multipart/form-data; | +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ | 2 | Connection | string | Да | keep-alive | +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ | 3 | Accept-version | string | Да | Основная (major) часть версии (сейчас 1) | +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ | 4 | ClientRequestID | string | Нет | Клиентский идентификатор | +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ | **Тело запроса** | +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ | 1 | priority | string | Да | Приоритет запроса. Варианты: | | | | | | | | | | | | - NORMAL; | | | | | | | | | | | | - HIGH | +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ | 2 | timeout | string | Нет | Предельное время ожидания выполнения запроса. | | | | | | | | | | | |В случае отсутствия параметра в запросе таймаут | | | | | | не выставляется | +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ | 3 | datamart | string | Нет | Витрина Поставщика данных, к которой | | | | | | производится обращение | +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ | 4 | mnemonic | string | Да | Мнемоника РЗ, к которому производится обращение | +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ | 5 | majorVersion | int | Нет | Версия РЗ, к которому производится обращение | | | | | | | | | | | Обязательное указание вместе | | | | | | с minorVersion. Если не | | | | | | указана, обращение к | | | | | | актуальной версии | | +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ | 6 | majorVersion | int | Нет | Версия РЗ, к которому производится обращение | | | | | | | | | | | Обязательное указание вместе | | | | | | с majorVersion. Если не | | | | | | указана, обращение к | | | | | | актуальной версии | | +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ | 7 | tableParams | array | Да | Описание передаваемого файла с данными для | | | | | | табличного параметра | +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ | 7.1 | name | string | Да | Наименование табличного параметра, | | | | | | соответствующее указанному в SQL-выражении | | | | | | в формате ``@`` | +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ | 7.2 | columns | array | Да | Перечень наименований столбцов и их типов, | | | | | | содержащихся в файле с данными для табличного | | | | | | параметра | +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ | 7.2.1 | name | string | Да | Наименование столбца | +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ | 7.2.2 | type | string | Да | Тип столбца | +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ | 8 | | | Да | Файл с данными для табличного параметра. Имя | | | | | | параметра соответствует наименованию табличного | | | | | | параметра | +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ | **file** | +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ | 8.1 | - | файл в | Да | Файл в формате CSV (поддерживаемый формат), | | | | формате | | передаваемый в параметре запроса | | | | CSV | | | +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ | **boundary** | +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ | 1 | Content-Disposition | string | Да | form-data; name=”table1”; filename=”table1.csv” | +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ .. _blob_sql_request: Выполнение запроса на получение BLOB по ссылке ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. _blob_request_onnect: HTTP-запрос (вариант 1) ############################### .. table:: HTTP-запрос (вариант 1) +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ | № | Параметр | Тип | Обязательность | Значение / описание | +=======+======================+=========+===============================+==================================================+ | 1 | Тип запроса (Method) | - | Да | GET | +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ | 2 | Путь (Path) | - | Да | /query/blob | +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ | **Параметры** | +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ | 1 | link | string | Да | Ссылка на вырузку BLOB | +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ | **Заголовки** | +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ | 1 | Accept | string | Да | application/vnd.ru.rtlabs.podd.agent+json; | | | | | | charset=utf-8 | +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ | 2 | Accept-version | string | Да | Основная (major) часть версии (сейчас 1) | +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ | 3 | ClientRequestID | string | Нет | Клиентский идентификатор в формате UUID. | | | | | | | | | | | | Потребителю рекомендуется в запросе BLOB по | | | | | | ссылке указать тот же сквозной идентификатор, | | | | | | что и при исходном запросе. | | | | | | | | | | | | Ответственность за соответствие идентификаторов | | | | | | лежит на Потребителе. | +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ Пример запроса: .. code-block:: GET “https://10.81.4.30:29354/query/blob/c005a0e7-0d26-4ce0-a1fa-10c8bdf4dfc5” .. _blob_broker_connect: HTTP-запрос (вариант 2) ##################################### .. table:: HTTP-запрос (вариант 2) +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ | № | Параметр | Тип | Обязательность | Значение / описание | +=======+======================+=========+===============================+==================================================+ | 1 | Тип запроса (Method) | - | Да | GET | +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ | 2 | Путь (Path) | - | Да | /regulated-query/blob | +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ | **Параметры** | +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ | 1 | link | string | Да | Ссылка на вырузку BLOB | +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ | **Заголовки** | +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ | 1 | Accept | string | Да | application/vnd.ru.rtlabs.podd.agent+json; | | | | | | charset=utf-8 | +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ | 2 | Accept-version | string | Да | Основная (major) часть версии (сейчас 1) | +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ | 3 | ClientRequestID | string | Нет | Клиентский идентификатор в формате UUID. | | | | | | | | | | | | Потребителю рекомендуется в запросе BLOB по | | | | | | ссылке указать тот же сквозной идентификатор, | | | | | | что и при исходном запросе. | | | | | | | | | | | | Ответственность за соответствие идентификаторов | | | | | | лежит на Потребителе. | +-------+----------------------+---------+-------------------------------+--------------------------------------------------+ Пример запроса: .. code-block:: GET “https://10.81.4.30:29354/regulated-query/blob/c005a0e7-0d26-4ce0-a1fa-10c8bdf4dfc5” .. _blob_response: Ответ на HTTP-запрос ######################## Допустимые коды возврата: - 200 – ок; - 400 – ошибка в запросе, информация об ошибке содержится в параметре «error»; - 403 – нет полномочий на выполнение запроса, в том числе при блокировке полномочий на стороне Поставщика (с отображением соответствующего текста ошибки); - 404 – получен запрос на обращение к недоступной ссылке на BLOB (истекло время жизни); - 406 – неподдерживаемая версия протокола (после внедрения поддержки обратной совместимости возвращается только для несуществующих версий); - 429 – ИС УВ временно заблокирована в связи с превышением лимитов; - 500 – системная ошибка (в связи в принятыми ограничениями по доступности код 500 предполагается только при сбое Агента); - 503 – система временно недоступна, возможно повторить запрос через 50 мс. Параметры ответа с кодом возврата 200: .. table:: Параметры ответа с кодом возврата 200: +-----+----------------------+----------+----------------+--------------------------------------------------+ | № | Параметр | Тип | Обязательность | Значение / описание | +=====+======================+==========+================+==================================================+ | 1 | responseCode | numeric | Да | Код возврата (HTTP-код) | +-----+----------------------+----------+----------------+--------------------------------------------------+ | **Заголовки** | +-----+----------------------+----------+----------------+--------------------------------------------------+ | 1 | Content-Type | string | Да | application/octet-stream | +-----+----------------------+----------+----------------+--------------------------------------------------+ | 2 | Content-Length | - | Да | Размер тела объекта в байтах | +-----+----------------------+----------+----------------+--------------------------------------------------+ | 3 | ClientRequestID | string | Нет | Клиентский идентификатор | +-----+----------------------+----------+----------------+--------------------------------------------------+ | **Тело сообщения** | +-----+----------------------+----------+----------------+--------------------------------------------------+ | 1 | | | Да | Содержимое полученного по ссылке файла (в виде | | | | | | массива байт) | +-----+----------------------+----------+----------------+--------------------------------------------------+ Пример ответа с кодом возврата 200: .. code-block:: HTTP/1.1 200 OK <Содержимое полученного по ссылке файла (в виде массива байт)> .. table:: Параметры ответа с кодом возврата, отличным от 200: +----+----------------------+----------+----------------+--------------------------------------------------+ | № | Параметр | Тип | Обязательность | Описание | +====+======================+==========+================+==================================================+ | 1 | responseCode | numeric | Да | Код возврата (HTTP-код) | +----+----------------------+----------+----------------+--------------------------------------------------+ | **Заголовки** | +----+----------------------+----------+----------------+--------------------------------------------------+ | 1 | Content-Type | string | Да | application/vnd.ru.rtlabs.podd.agent+json; | | | | | | version=1.0; charset=utf-8 | +----+----------------------+----------+----------------+--------------------------------------------------+ | **Тело сообщения** | +----+----------------------+----------+----------------+--------------------------------------------------+ | 1 | created_at | dateTime | Нет | Время формирования ответа | +----+----------------------+----------+----------------+--------------------------------------------------+ | 2 | query_id | string | Нет | Идентификатор запроса | +----+----------------------+----------+----------------+--------------------------------------------------+ | 3 | error | string | Нет | Текст ошибки | +----+----------------------+----------+----------------+--------------------------------------------------+ Пример ответа с кодом возврата, отличным от 200: .. code-block:: 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, код причины блокировки=<>, подробности: ‘Превышен лимит по количеству скачиваний по ссылке... ” } .. _respondent_rest_interface: REST-интерфейс Агента ПОДД для запросов к REST-сервису ИС Ответчика ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. _respondent_request: HTTP-запрос ^^^^^^^^^^^^ Все запросы выполняются в синхронном режиме в соответствии с загруженной в ПОДД СМЭВ спецификацией OpenApi REST-сервиса ИС Ответчика. Примеры спецификаций OpenAPI REST-сервисов ИС Ответчиков приведены в :numref:`respondent_rest_services`. Получение результата осуществляется путем выполнения HTTP-запроса от ИС Инициатора к Агенту ПОДД Ответчика. При выполнении запроса могут быть использованы все типы HTTP-методов (POST, GET, PUT и DELETE), выполняющих CRUD-операции (Create/Read/Update/Delete), которые используются в спецификациях OpenAPI, описывающих REST-сервисы ИС Ответчиков. Информация о формировании запроса приведена в :numref:`printable_form_output`. Клиентский идентификатор передаётся в опциональном заголовке ClientRequestID (тип string). .. _respondent_response: Ответ на HTTP-запрос ^^^^^^^^^^^^^^^^^^^^^^^ Ответ на запрос включает код возврата (статус выполнения операции) и, в зависимости от запрошенного метода, тело ответа, содержащее запрошенные данные и/или дополнительную информацию о результате выполнения операции, в соответствии с загруженной в ПОДД спецификацией OpenAPI REST-сервиса ИС Ответчика. :numref:`tab_podd_response_codes` содержит коды возврата ПОДД при ошибках выполнения запроса к REST-сервису ИС Ответчика. .. _tab_podd_response_codes: .. table:: Коды возврата ПОДД +---+-------------------------+-------------------------------------------------------------------------------------+ | № | Код возврата | Пример причины ошибки | +===+=========================+=====================================================================================+ | 1 | 500 Internal Server | - ошибка пересылки сообщений между сервисами | | | Error | | | | | - непредвиденная ошибка | +---+-------------------------+-------------------------------------------------------------------------------------+ | 2 | 401 Unauthorized | Ошибка проверки подписи | +---+-------------------------+-------------------------------------------------------------------------------------+ | 3 | 404 Not found | Спецификация OpenAPI REST-сервиса ИС Ответчика, к которой обращается запрос, не | | | | зарегистрирована в ПОДД | +---+-------------------------+-------------------------------------------------------------------------------------+ | 4 | 403 Forbidden | Нет прав на выполнение запроса к зарегистрированной в ПОДД спецификация OpenAPI | | | | REST-сервиса ИС Ответчика | +---+-------------------------+-------------------------------------------------------------------------------------+ | 5 | 400 Bad request | Запрос не соответствует зарегистрированной в ПОДД спецификации OpenAPI REST-сервиса | | | | ИС Ответчика | +---+-------------------------+-------------------------------------------------------------------------------------+ | 6 | 429 Too many requests | ИС УВ временно заблокирована в связи с превышением лимитов. Может возвращаться при | | | | использовании механизма с возможностью отправки большого запроса | +---+-------------------------+-------------------------------------------------------------------------------------+ | 7 | 503 Service unavailable | Oтветчик ограничил очередь запросов в клиенте. Может возвращаться при использовании | | | | механизма без возможности отправки большого запроса | +---+-------------------------+-------------------------------------------------------------------------------------+ .. _jdbc_interface: JDBC-интерфейс Агента ПОДД СМЭВ для SQL-запросов ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Агент ПОДД поддерживает специализированный протокол для исполнения запросов, эталонная реализация которого представлена JDBC-драйвером. Настройка JDBC-драйвера осуществляется с помощью передачи специализированной адресной строки: ``protocol://hostname:port/``, где: - ``protocol`` – протокол взаимодействия – значение всегда будет «podd»; - ``hostname`` – имя сервера или его IP-адрес; - ``port`` – порт, на котором Агент Потребителя данных предоставляет интерфейс для работы протокола взаимодействия в соответствии с «Руководством администратора ПОДД СМЭВ»[24]_. Клиентский идентификатор опционально передаётся в тексте SQL запроса первой строкой – комментарий с атрибутом ClientRequestID (тип string). .. code-block:: -- ClientRequestID: <клиентский идентификатор> CALL <мнемоника регламентированного SQL-запроса>(); .. [24] Размещен на портале ЕСКС – https://info.gosuslugi.ru/ .. _jdbc_driver: Пример использования JDBC-драйвера в «Kotlin» ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Для прикладного разработчика работа с JDBC драйвером PODD ничем не отличается от работы с обычным JDBC драйвером. Особенность только в URL, которым инициализируется драйвер. .. code-block:: 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 `ожидается успешное исполнение запроса вида "select 1" `() { Assertions.assertDoesNotThrow { val con = DriverManager.getConnection(getConnectionURI()) val statement = con.createStatement() statement.queryTimeout = 5 // таймаут на выполнение запроса - 5 секунд statement.setMaxRows(100) // ограничение выборки по кол-ву возвращаемых строк statement.executeQuery("select 1") val resultSet = statement.resultSet Assertions.assertEquals(1, resultSet.getInt(0)) } } @Test fun `ожидается ошибка при исполнении запроса "select 1" `() { Assertions.assertDoesNotThrow { val con = DriverManager.getConnection(getConnectionURI()) val statement = con.createStatement() try { statement.executeQuery("select 1") } catch (e: SQLException) { // получение кода ошибки Assertions.assertEquals(17089, e.errorCode) Assertions.assertEquals("PODD-17089: Ошибка при обработке запроса", e.message) } } } @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)) } } @Test fun `ожидается успешное применение табличных параметров `() { Assertions.assertDoesNotThrow { DriverManager.getConnection(getConnectionURI()).use { connection -> connection.prepareStatement("select * from @p1, @p2, oktmo.oktmo o where @p1.a = @p2.b and o.id = @p1.a").use { ps -> ps.queryTimeout = 10 // таймаут на выполнение запроса - 10 секунд ps.setMaxRows(100) // ограничение выборки по кол-ву возвращаемых строк ps as PoddPreparedStatement ps.addTableParam( "p1", listOf( ColumnInfo("a", ColumnType.INTEGER), ColumnInfo("av", ColumnType.STRING), ), iterator> { yield(arrayOf(1, "1_1")) yield(arrayOf(2, "1_2")) yield(arrayOf(3, "1_3")) }, ) ps.addTableParam( "p2", listOf( ColumnInfo("b", ColumnType.INTEGER), ColumnInfo("bv", ColumnType.STRING), ), iterator> { yield(arrayOf(1, "2_1")) yield(arrayOf(2, "2_2")) yield(arrayOf(3, "2_3")) }, ) ps.executeQuery().use { rs -> (1..rs.metaData.columnCount).forEach { println("${rs.metaData.getColumnName(it)}: ${rs.metaData.getColumnTypeName(it)}") } rs.readFully().forEach { row -> println() row.forEach { print("$it\t") } } } } } } } .. _jdbc_response_codes: Коды возврата ^^^^^^^^^^^^^^^^^ :numref:`tab_jdbc_response_codes` содержит допустимые коды возврата при ошибках выполнения запроса. .. _tab_jdbc_response_codes: .. table:: Коды возврата при ошибках выполнения запроса +----+--------------+-------------------------------------------------------------------------------------+ | № | Код возврата | Описание ошибки | +====+==============+=====================================================================================+ | 1 | 17001 | Внутренняя ошибка | +----+--------------+-------------------------------------------------------------------------------------+ | 2 | 17473 | Запрос не прошел проверку корректности (соответствие синтаксису) | +----+--------------+-------------------------------------------------------------------------------------+ | 3 | 17471 | ИС УВ временно заблокирована в связи с превышением лимитов | +----+--------------+-------------------------------------------------------------------------------------+ | 4 | 17800 | Запрос содержит указание на неподдерживаемую Витрину | +----+--------------+-------------------------------------------------------------------------------------+ | 5 | 17472 | Нет полномочий на выполнение запроса | +----+--------------+-------------------------------------------------------------------------------------+ | 6 | 17510 | Запрос отменен Потребителем | +----+--------------+-------------------------------------------------------------------------------------+ | 7 | 17520 | Запрос отменен по таймауту | +----+--------------+-------------------------------------------------------------------------------------+ | 8 | 17404 | Выполнение запроса прекращено из-за блокировки полномочий по результатам проверки | | | | на стороне Поставщика | +----+--------------+-------------------------------------------------------------------------------------+ | 9 | 17405 | Выполнение запроса прекращено из-за блокировки полномочий по результатам проверки | | | | на стороне Поставщика (заблокировано по умолчанию) | +----+--------------+-------------------------------------------------------------------------------------+ | 10 | 17406 | Выполнение запроса прекращено из-за блокировки по результату проверки SQL выражения | | | | на стороне Поставщика | +----+--------------+-------------------------------------------------------------------------------------+ .. _distribution_consumer_protocol: Протокол взаимодействия Агента ПОДД СМЭВ и Витрины данных по подписке Потребителя данных --------------------------------------------------------------------------------------------- Протокол коммуникации Агента ПОДД СМЭВ и Витрины данных по подписке, расположенных в контуре Потребителя данных, устроен в виде обмена сообщениями с использованием зарезервированных топиков брокера сообщений Apache Kafka. Всё взаимодействие между Витриной данных по подписке и Агентом ПОДД СМЭВ происходит исключительно с использованием брокера сообщений. .. _consumer_kafka_topics: Перечень топиков брокера сообщений Apache Kafka ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :numref:`tab_consumer_kafka_topics` содержит названия топиков брокера сообщений . .. _tab_consumer_kafka_topics: .. table:: Названия топиков брокера сообщений Apache Kafka +----+-------------------------------------+-------------------+----------------+--------------------------------------------+ | № | Топик | Публикатор | Подписчик | Передаваемый объект | +====+=====================================+===================+================+============================================+ | **Топики для обеспечения информационного обмена с использованием Рассылок** | +----+-------------------------------------+-------------------+----------------+--------------------------------------------+ | 1 | <префикс>.replication.in.rq | Агент | Витрина | Структура таблиц Витрины Поставщика данных | +----+-------------------------------------+-------------------+----------------+--------------------------------------------+ | 2 | <префикс>.replication.in.rs | Витрина | Агент | Уведомление об успешном создании структуры | | | | | | данных | +----+-------------------------------------+-------------------+----------------+--------------------------------------------+ | 3 | <префикс>.replication.in.err | Витрина | Агент | Уведомление об ошибке при создании | | | | | | структуры данных | +----+-------------------------------------+-------------------+----------------+--------------------------------------------+ | 4 | <префикс>.delta.notification.in | Агент | Витрина | Уведомление о наличии новых дельт у | | | | | | Поставщика | +----+-------------------------------------+-------------------+----------------+--------------------------------------------+ | 5 | <префикс>.command.podd | ИС Потребителя | Агент | Служебный топик для ручного перезапроса | | | | | | дельт | +----+-------------------------------------+-------------------+----------------+--------------------------------------------+ | 6 | <префикс>.delta.in.rq | Агент | Витрина | Запрос на прием дельты | +----+-------------------------------------+-------------------+----------------+--------------------------------------------+ | 7 | <префикс>.delta.in.tp | Агент | Витрина | Запрос на прием дельт по распределённой | | | | | | подписке | +----+-------------------------------------+-------------------+----------------+--------------------------------------------+ | 8 | <префикс>.delta.in.rs | Витрина | Агент | Уведомления об успешном применении дельт | | | | | | из пакета | +----+-------------------------------------+-------------------+----------------+--------------------------------------------+ | 9 | <префикс>.delta.in.err | Витрина | Агент | Уведомление об ошибке при применении дельт | | | | | | из пакета | +----+-------------------------------------+-------------------+----------------+--------------------------------------------+ | 10 | <префикс>.replication.cancel.in.rq | Агент | Витрина | Идентификатора отменяемой подписки | +----+-------------------------------------+-------------------+----------------+--------------------------------------------+ | 11 | <префикс>.replication.cancel.in.rs | Витрина | Агент | Результат (успешный или ошибка) отмены | | | | | | подписки | +----+-------------------------------------+-------------------+----------------+--------------------------------------------+ | **Топики для получения событий Витрины** | +----+-------------------------------------+-------------------+----------------+--------------------------------------------+ | 12 | <префикс>.scl.signal | Витрина | Агент | События Витрины для дальнейшей передачи в | | | | | | СЦЛ | +----+-------------------------------------+-------------------+----------------+--------------------------------------------+ .. _respondent_protocol: Протокол взаимодействия Агента ПОДД СМЭВ и ИС Ответчика ----------------------------------------------------------- Взаимодействие Агента ПОДД СМЭВ и REST-сервиса на стороне ИС Ответчика осуществляется в соответствии со спецификацией OpenAPI, описывающей REST-сервис ИС Ответчика и загруженной в ПОДД СМЭВ. Для использования запросов к REST-сервису ИС Ответчика через ПОДД СМЭВ необходимо произвести настройки, указанные в Руководстве администратора Агента ПОДД СМЭВ [25]_. .. [25] Руководство администратора Агента ПОДД СМЭВ размещено на портале ЕСКС – https://info.gosuslugi.ru/