From 0ade363fa8eb3331596bd8ad76950ec15f3c38b2 Mon Sep 17 00:00:00 2001 From: Roman Matveev Date: Mon, 15 Sep 2025 13:11:43 +0300 Subject: [PATCH] the object is null --- __data__/smev-message-exchange-basic-1.1.xsd | 380 ++++++++++ __data__/smev-message-exchange-types-1.1.xsd | 697 +++++++++++++++++++ __tests__/XMLMarshaller.js | 10 + lib/XMLMarshaller.js | 4 +- 4 files changed, 1089 insertions(+), 2 deletions(-) create mode 100644 __data__/smev-message-exchange-basic-1.1.xsd create mode 100644 __data__/smev-message-exchange-types-1.1.xsd diff --git a/__data__/smev-message-exchange-basic-1.1.xsd b/__data__/smev-message-exchange-basic-1.1.xsd new file mode 100644 index 0000000..33fa907 --- /dev/null +++ b/__data__/smev-message-exchange-basic-1.1.xsd @@ -0,0 +1,380 @@ + + + + Базовые типы. + + + + + + + + + Содержательная часть сообщения СМЭВ. + + + + Корневой элемент XML-документа запроса присоединять сюда. + + + + + + + + Заголовки файлов, приложенных к СМЭВ-сообщению. + Заголовки отделены от содержимого вложений. + Это нужно потому, что заголовки должны попадать под ЭП-ОВ, + а содержимое - должно не попадать (иначе не будет работать MTOM). + + + + + + + + + + + + Файл, приложенный к СМЭВ-сообщению. + Имя файла не передаётся; вложения идентифицируются только идентификаторами внутри сообщения. + + + + + + + Идентификатор вложения. Ссылка на соответствующий //AttachmentContent/@Id + + + + + Тип контента. + + + ЭЦП в формате PKCS#7 detached. Подписывать ключом ЭП-СП. + + + + + + + Cодержимое вложенных файлов. + У элемента списка, тип base64Binary и наличие атрибута expectedContentTypes - подсказка для frameworks типа JAX-WS передавать содержимое этого элемента по MTOM протоколу. + Кроме того, значение expectedContentTypes="application/octet-stream" - подсказка JAX-WS дать доступ к этому элементу через InputStream/OutputStream. + + + + + + + + + + + + + + + + + + + + + + + Идентификатор файла. Ссылка на соответствующий файл. + + + + + Пользователь. + + + Пароль. + + + Имя файла. + + + + + + + Содержимое вложенного файла. + Значение атрибута attachmentId должно быть уникально среди всех элементов и атрибутов СМЭВ-сообщения, имеющих тип xs:ID. + + + + + + + + + + + Заголовки файлов, приложенных к СМЭВ-сообщению. + Заголовки отделены от содержимого вложений. + Это нужно потому, что заголовки должны попадать под ЭП-ОВ, + а содержимое - должно не попадать (иначе не будет работать MTOM). + + + + + + + + + + + + Ссылка на файл, приложенный к СМЭВ-сообщению. + + + + + + + Идентификатор файла. Ссылка на соответствующий файл. + + + + + Хэш файла. + + + Тип контента. + + + ЭЦП в формате PKCS#7 detached. Подписывать ключом ЭП-СП. + + + + + + + Строковое представление UUID. + В СМЭВ UUID используются в качестве идентификаторов сообщений. + Идентификаторы присваиваются сообщеням отправителями. + + + + + + + + Тип для подписанных ссылок на сообщения СМЭВ. + + + + + + + + + + + + Ссылка на сообщение, получение которого подтверждается методом Ack. + Сюда нужно писать Id СМЭВ-сообщения, который берётся + из //GetRequestResponse/.../SenderProvidedRequestData/MessageID/text() либо + из //GetResponseResponse/.../SenderProvidedRequestData/MessageID/text(). + + + + + + + + + + true, если ЭП-СМЭВ прошла валидацию и сообщение передано ИС. false, если ЭП-СМЭВ отвергнута, и сообщение проигнорировано. + + + + + + + + + + + Элекронная подпись в формате XMLDSig. + + + + + + + Собственно подпись, по спецификации XMLDSig. + Объявлена как any для того, чтобы инструменты типа JAXB не генерировали классов для пространства имён + http://www.w3.org/2000/09/xmldsig#. + Это, в свою очередь, нужно потому, что инструменты, генерирующие и проверяющие ЭЦП (напр. Apache Santuario) + работают с DOM-деревьями, а не с JAXB-объектами. + + + + + + + Типы вложений, в формате RFC-2046. + + + + + + + + + Селектор, с помощью которого при приёме запроса или ответа + можно задать фильтр по типу запроса (ответа). + Поскольку тип запроса или ответа однозначно определяется полным именем + корневого XML-элемента его бизнес-данных, + селектор представляет из себя структуру для задания этого имени. + Если селектор пуст, это значит, что нужно принять запрос (ответ) + без фильтрации по типам. + + + + + + + + + Текущая дата и время. + + + + + Идентификатор нода. + + + + + + + + + + + Запрос с таким Id не найден в БД СМЭВ. + + + Запрос находится в очереди на асинхронную валидацию. + + + Запрос доставляется поставщику. + + + Запрос не прошёл асинхронную валидацию. + + + Обрабатывается поставщиком сервиса. + + + Запрос выполнен или отвергнут поставщиком сервиса; ответ находится в очереди СМЭВ. + + + Запрос отменён потребителем сервиса. + + + Ответ получен потребителем сервиса. + + + + + Тип взаимодействия + + + Взаимодействие портала государственных и/или муниципальных услуг с органом власти. + + + Взаимодействие между органами власти. + + + Взаимодействие между различными информационными системами одного органа исполнительной власти через СМЭВ. + + + Взаимодействие информационно-платежного шлюза с поставщиками начислений для оплаты услуг в электронном виде. + + + Взаимодействие информационно-платежного шлюза с системой УНИФО ФК для получения начислений и фактов оплаты для пользователей ПГУ. + + + Взаимодействие ОИВ с системой УНИФО ФК для передачи начислений и получения фактов оплаты. + + + Другие типы взаимодействия. + + + Не удалось определить тип взаимодействия. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Тип элемента, который передаёт информацию фактом своего наличия. + + + + + + + + + + + \ No newline at end of file diff --git a/__data__/smev-message-exchange-types-1.1.xsd b/__data__/smev-message-exchange-types-1.1.xsd new file mode 100644 index 0000000..9605ae9 --- /dev/null +++ b/__data__/smev-message-exchange-types-1.1.xsd @@ -0,0 +1,697 @@ + + + + + Типы и элементы для веб-сервиса, который СМЭВ предоставляет всем участникам межведомственного взаимодействия для обмена сообщениями. + + + + + + + + + + + Параметры метода "Послать запрос". + + + + Содержательная часть запроса + служебные данные, заполняемые отправителем. + + + Вложенные файлы - содержимое. Содержимое вынесено из-под ЭП-ОВ, чтобы не нарушать работу MTOM. + + + + + ЭП-ОВ или ЭП-ПГУ. Подписан элемент //SenderProvidedRequestData. + Подпись оставлена необязательной, чтобы клиентов можно было тестировать с упрощёнными эмуляторами СМЭВ. + Реальный СМЭВ отбивает сообщения без ЭП-ОВ или ЭП-ПГУ. + + + + + + + + + + Возвращаемое значение метода "Послать запрос": запрос принят. + Если запрос не может быть принят, информация о причине отказа передаётся через SOAP fault, см. WSDL-описание сервиса. + + + + + + + + Данные о сообщении: ID, присвоенный СМЭВ, дата приёма по часам СМЭВ, результат маршрутизации, etc. + + + + + + + ЭП-СМЭВ. Подписан элемент //MessageMetadata. + Подпись оставлена необязательной, чтобы клиентов можно было тестировать с упрощёнными эмуляторами СМЭВ. + + + + + + + + Параметры метода "Послать ответ на запрос". + + + + + + ЭП-ОВ или ЭП-ПГУ. Подписан элемент //SenderProvidedResponseData. + + + + + + + + Возвращаемое значение метода "Послать ответ на запрос": ответ принят. + Если ответ не может быть принят, информация о причине отказа передаётся через SOAP fault, см. WSDL-описание сервиса. + + + + + + + + Данные о сообщении: ID, присвоенный СМЭВ, дата приёма по часам СМЭВ, результат маршрутизации, etc. + + + + + + + ЭП-СМЭВ. Подписан элемент //MessageMetadata. + Подпись оставлена необязательной, чтобы клиентов можно было тестировать с упрощёнными эмуляторами СМЭВ. + + + + + + + + + + Параметры метода "получить сообщение из моей входящей очереди запросов, если очередь не пуста". + Какую входящую очередь смотреть - определаятся по владельцу сертификата, входящего в состав ЭЦП, + и селектору типа запроса. + + + + + + + + + ЭП-ОВ или ЭП-ПГУ. Подписан элемент //Id. + + + + + + + + + + Возвращаемая структура метода "получить сообщение из моей входящей очереди запросов, если очередь не пуста". + + + + + + + + + + + + + + + Сообщение об статусе асинхронной обработки в СМЭВ. + + + + + + + + + ЭП-СМЭВ. Подписан элемент preceding-sibling: + + + + + + + + Параметры метода "получить сообщение из моей входящей очереди запросов, если очередь не пуста". + Какую входящую очередь смотреть - определаятся по владельцу сертификата, входящего в состав ЭЦП, + и селектору типа запроса. + + + + + + + + См. описание {urn://x-artefacts-smev-gov-ru/services/message-exchange/types/basic/1.1}MessageTypeSelector + + + + + + + ЭП-ОВ или ЭП-ПГУ. Подписан элемент //MessageTypeSelector. + + + + + + + + + + Параметры метода "получить сообщение из моей входящей очереди ответов, если очередь не пуста". + Какую входящую очередь смотреть - определаятся по владельцу сертификата, входящего в состав ЭЦП, + и селектору типа _ответа_. + + + + + + + + См. описание {urn://x-artefacts-smev-gov-ru/services/message-exchange/types/basic/1.1}MessageTypeSelector + + + + + + + ЭП-ОВ или ЭП-ПГУ. Подписан элемент //MessageTypeSelector. + + + + + + + + + + Возвращаемая структура метода "получить сообщение из моей входящей очереди запросов, если очередь не пуста". + + + + + + + + Полученное сообщение. Если этот элемент отсутствует, это значит, что входящая очередь пуста. + + + + + + + + + + + + + ЭП-СМЭВ. Подписан элемент //Request, либо //Cancel + + + + + + + + + + + Возвращаемая структура метода "получить сообщение из моей входящей очереди, если очередь не пуста". + + + + + + + Если у GetResponseResponse нет child element, это значит, что входящая очередь пуста. + + + + Ответ, присланный поставщиком данных. + + + + + + ЭП-СМЭВ. Подписан элемент preceding-sibling::tns:Response + + + + + + + + + + + + + Категория статуса. + + + Описание процессинга в человекочитаемом виде. + + + + + + + + + + + + + + + Параметры метода "Подтверждение получения сообщения". + + + + + ЭП-ОВ или ЭП-ПГУ. Подписан элемент preceding-sibling::basic:AckTargetMessage. + + + + + + Возвращаемое значение метода "Подтверждение получения сообщения". + + + + + Параметры метода "получить статистику входящей очереди". + Какую входящую очередь смотреть - определаятся по владельцу сертификата, входящего в состав ЭЦП. + + + + + + + + Идентификатор нода. + + + + + + + + ЭП-ОВ или ЭП-ПГУ. Подписан элемент //СurrentTimestamp. + + + + + + + + + + + + + + + + + + + + + + + + + Идентификатор, присвоенный сообщению отправителем. + Генерируется в соответствии с RFC-4122, по варианту 1 (на основании MAC-адреса и текущего времени). + + + + + + + Идентификатор сообщения, порождающего цепочку сообщений. + При отправке подчиненных сообщений значение соответствует MessageID корневого сообщения цепочки сообщений. + Для корневого сообщения значение совпадает с MessageID + + + + + + + Идентификатор кода транзакции. + + + + + + + Идентификатор нода отправителя. + + + + + + + Ограничение жизни сообщения. + + + + + Содержательная часть запроса, XML-документ. + + + + + ЭП-СП содержательной части запроса. + Подписывается элемент, находящийся сразу под MessagePrimaryContent. + Хотя этот элемент не обязателен, поставщик данных может потребовать, + чтобы в запросах определённых типов ЭП-СП всегда была. + Это вызвано тем, что в ряде случаев, согласно ФЗ, сведения могут предоставляться только по запросам + должностных лиц определённого уровня. + + + + + Заголовки вложенных файлов. + + + Заголовки файлов по ссылке. + + + + + Информация о бизнес-процессе, в рамках которого пересылается данное сообщение. + Формат данных определяется в отдельной схеме (схемах). + На текущий эта информация не обязательна для заполнения отправителем. + + + + + + + + + + + + Если этот элемент присутствует, то запрос - тестовый. + В этом случае, ИС-поставщик данных должна гарантировать, что её данные не будут изменены + в результате выполнения этого запроса. + + + + + + + + + + + + + + Идентификатор, присвоенный сообщению отправителем. + Генерируется в соответствии с RFC-4122, по варианту 1 (на основании MAC-адреса и текущего времени). + + + + + + + Адрес доставки ответа. Копируется из запроса, //GetRequestResponse/ReplyTo/text() + + + + + + + Содержательная часть ответа, XML-документ. + + + ЭП-СП содержательной части ответа. Подписывается элемент, находящийся сразу под MessagePrimaryContent. + + + Заголовки вложенных файлов. + + + Заголовки файлов по ссылке. + + + + + + + Код причины отклонения запроса. + + + Причина отклонения запроса, в человекочитаемом виде. + + + + + + + + + Код бизнес статуса запроса. + + + + + + + + + + + Бизнес статус запроса, в человекочитаемом виде. + + + + + + + + + + + + + + + + + + + + + + + + + + + Информация об отправителе, дате отправки, маршрутизации сообщения, и другая (см. определение типа). + Все данные заполняются СМЭВ. + Элемент //MessageMetadata/SendingTimestamp содержит дату и время, начиная с которых отсчитывается срок исполнения запроса. + Остальные данные предназначены для целей анализа (машинного и ручного) качества обслуживания + информационной системы - получателя сообщения, + а также для предоставления службе поддержки оператора СМЭВ в случае необходимости. + + + + + + + + + Аналог обратного адреса; непрозрачный объект, по которому СМЭВ сможет вычислить, кому доставить ответ на этот запрос. + При отправке ответа нужно скопировать это значение в //SenderProvidedResponseData/To/text(). + N.B. Формат обратного адреса не специфицирован, и может меняться со временем. + Больше того, в запросах, пришедших от одного и того же отправителя через сколь угодно малый промежуток времени, + обратный адрес не обязан быть одним и тем же. + Если получатель хочет идентифицировать отправителя, можно использовать либо маршрутную информацию СМЭВ + (//GetMessageIfAnyResponse/SMEVRoutingInfo/Sender/*), либо сертификат отправителя + (//GetMessageIfAnyResponse/CallerInformationSystemSignature/xmldsig:Signature/...) + + + + + ЭП-ОВ или ЭП-ПГУ отправителя. Подписан элемент //SenderProvidedRequestData + + + + + + + + + + + + + + Идентификатор сообщения, порождающего цепочку сообщений. + При отправке подчиненных сообщений значение соответствует MessageID корневого сообщения цепочки сообщений. + Для корневого сообщения значение совпадает с MessageID + + + + + + + + + ЭП-ОВ или ЭП-ПГУ отправителя. Подписан элемент //SenderProvidedResponseData + + + + + + + + + + + + Ссылка на запрос, который нужно отменить. + Сюда нужно писать ID СМЭВ-сообщения, который был передан при отправке запроса в элементе + //SendRequestRequest/SenderProvidedRequestData/MessageID. + + + + + + + Идентификатор, присвоенный СМЭВ уведомлению об отмене. + Генерируется в соответствии с RFC-4122, по варианту 1 (на основании MAC-адреса и текущего времени). + + + + + + ЭП-ОВ или ЭП-ПГУ отправителя. Подписан элемент //SenderProvidedCancelData + + + + + + + + Маршрутная информация, заполняемая СМЭВ. + + + + + Информация об отправителе сообщения. + + + + Мнемоника отправителя. Для машинной обработки. Вычисляется на основании данных сетрификата. + + + + + Наименование отправителя в форме, удобной для восприятия человеком. + Вычисляется на основании данных сертификата. + Не обязано полностью совпадать с официальным названием организации или органа власти. + + + + + + + + Дата и время отправки сообщения в СМЭВ. + + + + + + + Получатель сообщения (вычислен маршрутизатором). + Для широковещательных сообщений не заполняется. + + + + + + Мнемоника. Для машинной обработки. + + + Наименование в форме, удобной для восприятия человеком. + + + + + + Дополнительная информация о сообщении. + + + + + + Тип сообщения. Вычисляется СМЭВ на основании полного имени (qualified name) корневого XML-элемента сообщения. + Например, "Заявка на получение выписки из ЕГРИП". + Для ответов на запросы этот элемент опускается. + + + + + Тип взаимодействия, например, портал госуслуг - ОИВ. + + + + + + Дата и время доставки сообщения, по часам СМЭВ. + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/__tests__/XMLMarshaller.js b/__tests__/XMLMarshaller.js index 3261650..4cbcecf 100644 --- a/__tests__/XMLMarshaller.js +++ b/__tests__/XMLMarshaller.js @@ -286,6 +286,16 @@ test ('20319', async () => { }) +test ('null', () => { + + const xs = new XMLSchemata (Path.join (__dirname, '..', '__data__', 'smev-message-exchange-types-1.1.xsd')) + + const xml = xs.stringify ({AckResponse: null}) + + expect (xml).toMatch ('ns2:AckResponse') + +}) + test ('nillable', () => { const xs = getXSSync (Path.join (__dirname, '..', '__data__', 'F9ASyncService_1.xsd')) diff --git a/lib/XMLMarshaller.js b/lib/XMLMarshaller.js index 1591d35..dd5938e 100644 --- a/lib/XMLMarshaller.js +++ b/lib/XMLMarshaller.js @@ -77,7 +77,7 @@ const XMLMarshaller = class { } - if (data [XSI_TYPE]) { + if (data && data [XSI_TYPE]) { let {targetNamespace} = this.xs.getSchemaByLocalName(data [XSI_TYPE]) @@ -109,7 +109,7 @@ const XMLMarshaller = class { const {attributes: {type}, children} = node - if (data [XSI_TYPE]) { + if (data && data [XSI_TYPE]) { let d = {}; for (let k in data) d [k] = data [k] this.appendElementBody (this.schema.get (data [XSI_TYPE]), d) }