REST-сервис meta-data-driven¶
Модуль предназначен для получения JSON-файлов от других информационных систем в свободной структуре данных. В результате работы запросов meta-data-driven структура данных JSON трансформируется в структуру, требуемую для корректной загрузки данных в Юниверс MDM.
Модуль помогает избегать этап ручной переработки структуры JSON в структуру, используемую Юниверс MDM. JSON-файлы могут приходить от информационной системы любого вида. Структура данных JSON может быть любой.
meta-data-driven заменяет стандартный способ загрузки данных в систему, загружая данные по своим алгоритмам и выполняя тем самым стороннюю интеграцию. Способы генерации внешнего ключа для модуля работают как для внешней интеграции.
Перечень запросов:
Схема данных:
Работа с данными:
Базовый URL запросов: http://localhost:9080/universe-backend/api/
URL для Swagger: http://<хост>:<порт>/universe-backend/api/meta-data-driven/v1/api-docs?url=/universe-backend/api/meta-data-driven/v1/openapi.json#/Data%20schema/batchRequestSchema
Аутентификация¶
Все запросы требуют указания токена аутентификации. Для получения токена нужно выполнить следующий запрос:
Метод: POST
Путь запроса: {URL стенда}/universe-backend/api/v2/core/authentication/login
Пример запроса:
curl --location '{URL_стенда}/universe-backend/api/v2/core/authentication/login' \
--header 'Content-Type: application/json' \
--data '{
"userName": "имя пользователя",
"password": "пароль",
"locale":"ru"
}'
Пример ответа:
{
"token": "b2682a43-010f-46eb-a82a-43010f66eb1f"
}
Схема данных¶
Данные имеют динамическую структуру, зависящую от модели данных. Для получения структуры данных сервис предоставляет JSON схемы входящих/исходящих записей.
Схема входящих записей¶
Метод используется для получения описания модели данных реестра/справочника из MDM. В ответе содержится описание атрибутов и служебных атрибутов объекта.
Метод: GET
Путь запроса: {URL_стенда}/universe-backend/api/meta-data-driven/v1/schema/input/COUNTRY
Пример запроса:
curl -X 'GET' \
'http://localhost:9081/universe-backend/api/meta-data-driven/v1/schema/input/COUNTRY' \
-H 'accept: application/json' \
-H 'Authorization: fdff3b9d-87b3-4a57-bf3b-9d87b33a5783'
Пример ответа HTTP 200:
{
"$id": "/meta-data-driven/v1/schema/input/COUNTRY",
"$schema": "http://json-schema.org/draft-07/schema",
"description": "Страны",
"type": "object",
"properties": {
"externalId": {
"type": "string"
},
"sourceSystem": {
"type": "string"
},
"patch": {
"type": "boolean"
},
"attributes": {
"type": "object",
"description": "Страны",
"properties": {
"KOD": {
"type": "string",
"description": "Код страны ISO"
},
"NAME": {
"type": "string",
"description": "Краткое наименование"
},
"FULL_NAME": {
"type": "string",
"description": "Полное наименование"
},
"ENG_NAME": {
"type": "string",
"description": "Английское наименование"
}
},
"required": [
"KOD",
"NAME"
]
}
}
}
Схема исходящих записей¶
Метод используется для получения описания нотификации. В ответе содержится описание атрибутов и служебных атрибутов нотификации.
Метод: GET
Путь запроса: {URL_стенда}/universe-backend/api/meta-data-driven/v1/schema/output/COUNTRY
Пример запроса:
curl -X 'GET' \
'http://localhost:9081/universe-backend/api/meta-data-driven/v1/schema/output/COUNTRY' \
-H 'accept: application/json' \
-H 'Authorization: fdff3b9d-87b3-4a57-bf3b-9d87b33a5783'
Пример ответа HTTP 200:
{
"$id": "/meta-data-driven/v1/schema/output/COUNTRY",
"$schema": "http://json-schema.org/draft-07/schema",
"type": "object",
"properties": {
"etalonId": {
"type": "string"
},
"entityName": {
"type": "string"
},
"externalKey": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"sourceSystem": {
"type": "string"
}
}
},
"attributes": {
"type": "object",
"description": "Страны",
"properties": {
"KOD": {
"type": "string",
"description": "Код страны ISO"
},
"NAME": {
"type": "string",
"description": "Краткое наименование"
},
"FULL_NAME": {
"type": "string",
"description": "Полное наименование"
},
"ENG_NAME": {
"type": "string",
"description": "Английское наименование"
}
},
"required": [
"KOD",
"NAME"
]
}
}
}
Схема batch-запроса¶
Метод используется для получения перечня объектов модели данных MDM. Описание каждого объекта можно получить в ответе на запрос "Схема входящих записей".
Метод: GET
Путь запроса: {URL_стенда}/universe-backend/api/meta-data-driven/v1/data/schema/batch-request
Пример запроса:
curl -X 'GET' \
'http://localhost:9081/universe-backend/api/meta-data-driven/v1/data/schema/batch-request' \
-H 'accept: application/json' \
-H 'Authorization: fdff3b9d-87b3-4a57-bf3b-9d87b33a5783'
Пример ответа HTTP 200:
{
"$id": "/meta-data-driven/v1/schema/batch-request",
"$schema": "http://json-schema.org/draft-07/schema",
"type": "object",
"properties": {
"resolveResult": {
"type": "boolean"
},
"records": {
"type": "object",
"properties": {
"OKV_S": {
"type": "array",
"items": {
"$ref": "/meta-data-driven/v1/schema/input/OKV_S"
}
},
"ContactType": {
"type": "array",
"items": {
"$ref": "/meta-data-driven/v1/schema/input/ContactType"
}
},
"COUNTRY": {
"type": "array",
"items": {
"$ref": "/meta-data-driven/v1/schema/input/COUNTRY"
}
},
"OKEI_S": {
"type": "array",
"items": {
"$ref": "/meta-data-driven/v1/schema/input/OKEI_S"
}
},
"OKOPF": {
"type": "array",
"items": {
"$ref": "/meta-data-driven/v1/schema/input/OKOPF"
}
},
"OKVED": {
"type": "array",
"items": {
"$ref": "/meta-data-driven/v1/schema/input/OKVED"
}
},
"OKFS": {
"type": "array",
"items": {
"$ref": "/meta-data-driven/v1/schema/input/OKFS"
}
},
"cars": {
"type": "array",
"items": {
"$ref": "/meta-data-driven/v1/schema/input/cars"
}
},
"Legal_Entity": {
"type": "array",
"items": {
"$ref": "/meta-data-driven/v1/schema/input/Legal_Entity"
}
},
"Person": {
"type": "array",
"items": {
"$ref": "/meta-data-driven/v1/schema/input/Person"
}
},
"article": {
"type": "array",
"items": {
"$ref": "/meta-data-driven/v1/schema/input/article"
}
}
}
}
}
}
Схема batch-ответа¶
Метод используется для получения перечня объектов, которые содержат описание нотификации для реестра/справочника MDM.
Метод: GET
Путь запроса: {URL_стенда}/universe-backend/api/meta-data-driven/v1/data/schema/batch-response
Пример ответа HTTP 200:
{
"$id": "/meta-data-driven/v1/schema/batch-response",
"$schema": "http://json-schema.org/draft-07/schema",
"type": "object",
"properties": {
"records": {
"type": "object",
"properties": {
"OKV_S": {
"type": "array",
"items": {
"type": "object",
"properties": {
"record": {
"$ref": "/meta-data-driven/v1/schema/output/OKV_S"
},
"details": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
},
"ContactType": {
"type": "array",
"items": {
"type": "object",
"properties": {
"record": {
"$ref": "/meta-data-driven/v1/schema/output/ContactType"
},
"details": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
},
"COUNTRY": {
"type": "array",
"items": {
"type": "object",
"properties": {
"record": {
"$ref": "/meta-data-driven/v1/schema/output/COUNTRY"
},
"details": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
},
"OKEI_S": {
"type": "array",
"items": {
"type": "object",
"properties": {
"record": {
"$ref": "/meta-data-driven/v1/schema/output/OKEI_S"
},
"details": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
},
"OKOPF": {
"type": "array",
"items": {
"type": "object",
"properties": {
"record": {
"$ref": "/meta-data-driven/v1/schema/output/OKOPF"
},
"details": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
},
"OKVED": {
"type": "array",
"items": {
"type": "object",
"properties": {
"record": {
"$ref": "/meta-data-driven/v1/schema/output/OKVED"
},
"details": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
},
"OKFS": {
"type": "array",
"items": {
"type": "object",
"properties": {
"record": {
"$ref": "/meta-data-driven/v1/schema/output/OKFS"
},
"details": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
},
"cars": {
"type": "array",
"items": {
"type": "object",
"properties": {
"record": {
"$ref": "/meta-data-driven/v1/schema/output/cars"
},
"details": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
},
"Legal_Entity": {
"type": "array",
"items": {
"type": "object",
"properties": {
"record": {
"$ref": "/meta-data-driven/v1/schema/output/Legal_Entity"
},
"details": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
},
"Person": {
"type": "array",
"items": {
"type": "object",
"properties": {
"record": {
"$ref": "/meta-data-driven/v1/schema/output/Person"
},
"details": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
},
"article": {
"type": "array",
"items": {
"type": "object",
"properties": {
"record": {
"$ref": "/meta-data-driven/v1/schema/output/article"
},
"details": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
}
}
}
Работа с данными¶
Сохранение единичной записи¶
Метод используется для создания новой записи или для изменения существующей.
В качестве идентификатора используется связка externalId + source name. В случае отсутствия атрибута source name в запросе, запись будет создана/обновлена от имени universe.
Существует возможность обновить запись частично, передав только те атрибуты, которые требуется изменить. Для этого надо использовать параметр patch
со значением true
или false
. Параметр true
означает, что мы обновляем предыдущую ревизию (если запись имеет несколько ревизий) от имени источника, который указывается в запросе. Если мы выставим параметр на значение false
то это будет значить, что мы обновляем последнюю ревизию записи (если запись имеет несколько ревизий).
Метод: POST
Путь запроса: {URL_стенда}/universe-backend/api/meta-data-driven/v1/data/{entity-name}
Пример запроса:
curl -X 'POST' \
'http://localhost:9081/universe-backend/api/meta-data-driven/v1/data/OKOPF' \
-H 'accept: application/json' \
-H 'Authorization: fae5b2f0-2b1c-42db-a5b2-f02b1c52dbcd' \
-H 'Content-Type: application/json' \
-d '{
"externalId": "my_unique_id_2",
"attributes": {
"KOD": 99998,
"IS_ACTUAL": true,
"NAME": "Наименование"
}
}'
Пример ответа HTTP 200:
{
"record": {
"etalonId": "40c8610a-755f-11ed-9fbd-73aae866f4c6",
"entityName": "OKOPF",
"externalKey": {
"id": "my_unique_id_2",
"sourceSystem": "universe"
},
"attributes": {
"KOD": 99998,
"IS_ACTUAL": true,
"NAME": "Наименование"
},
"relations": null
},
"details": []
}
Batch сохранение¶
Метод используется для массового создания новых записей или изменения существующих. В качестве идентификатора используется externalId.
Метод: POST
Путь запроса: {URL_стенда}/universe-backend/api/meta-data-driven/v1/data/save-batch
Пример запроса:
curl -X 'POST' \
'{URL_стенда}/universe-backend/api/meta-data-driven/v1/data/save-batch' \
-H 'accept: application/json' \
-H 'Authorization: fdff3b9d-87b3-4a57-bf3b-9d87b33a5783' \
-H 'Content-Type: application/json' \
-d '{
"records": {
"OKOPF": [
{
"externalId": "my_unique_id",
"attributes": {
"KOD": 99999,
"IS_ACTUAL": true,
"NAME": "Наименование"
}
}
]
},
"resolveResult": true
}'
Пример ответа HTTP 200:
{
"records": {
"OKOPF": [
{
"record": {
"etalonId": "1bc560e6-755a-11ed-be37-73aae866f4c6",
"entityName": "OKOPF",
"externalKey": {
"id": "my_unique_id",
"sourceSystem": "universe"
},
"attributes": {
"KOD": 99999,
"IS_ACTUAL": true,
"NAME": "Наименование"
},
"relations": null
},
"details": []
}
]
}
}
Запрос записи по внешнему ключу¶
Метод используется для получения информации о записи. В качестве идентификатора используется связка externalId + source-system.
Метод: GET
Путь запроса: {URL_стенда}/universe-backend/api/meta-data-driven/v1/data/{entity-name}/{source-system}/{external-id}
Пример запроса:
curl -X 'GET' \
'http://localhost:9081/universe-backend/api/meta-data-driven/v1/data/OKOPF/universe/eid_1' \
-H 'accept: application/json' \
-H 'Authorization: fdff3b9d-87b3-4a57-bf3b-9d87b33a5783'
Пример ответа HTTP 200:
{
"etalonId": "dcb81331-7165-11ed-969f-73aae866f4c6",
"entityName": "OKOPF",
"externalKey": {
"id": "eid_1",
"sourceSystem": "universe"
},
"attributes": {
"KOD": 10001,
"IS_ACTUAL": true,
"NAME": "Наименование"
},
"relations": null
}
Запрос записи по эталонному ключу¶
Метод используется для получения информации о записи по etalonId.
Метод: GET
Путь запроса: {URL_стенда}/universe-backend/api/meta-data-driven/v1/data/{entity-name}/{etalon-id}
Пример простого запроса:
curl -X 'GET' \
'http://localhost:9081/universe-backend/api/meta-data-driven/v1/data/OKOPF/dcb81331-7165-11ed-969f-73aae866f4c6' \
-H 'accept: application/json' \
-H 'Authorization: fdff3b9d-87b3-4a57-bf3b-9d87b33a5783'
Пример ответа HTTP 200:
{
"etalonId": "dcb81331-7165-11ed-969f-73aae866f4c6",
"entityName": "OKOPF",
"externalKey": {
"id": "eid_1",
"sourceSystem": "universe"
},
"attributes": {
"KOD": 10001,
"IS_ACTUAL": true,
"NAME": "Наименование"
},
"relations": null
}
Пример запроса записи, которая содержит связь и простые атрибуты:
GET http://universe-mdm-ea:8082/universe-backend/api/meta-data-driven/v1/data/organizations/3910b197-8225-11ee-b6df-d37c61cbe6d3
HTTP/1.1 200
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive
{
"etalonId": "3910b197-8225-11ee-b6df-d37c61cbe6d3",
"entityName": "organizations",
"externalKey": {
"id": "30b62bb0-8225-11ee-a174-afd210c0bfe3",
"sourceSystem": "universe"
},
"createAt": "2023-11-13T13:04:49.335",
"updateAt": "2023-11-13T13:04:49.335",
"attributes": {
"head_patronymic": "Михайлович",
"individual_entrepreneur": false,
"Conmtacts": [],
"contact_phone_number": "+7(978)493-03-20",
"status_name": "",
"head_position": "ИО директора",
"head_first_name": "Алексей",
"okopf_name": "Частные учреждения",
"okfs_id": "34",
"head_surname": "Ровнов",
"okopf_id": "75500",
"okfs_name": "Совместная частная и иностранная собственность",
"full_name": "ООО Аврора",
"okved_id": "97.00",
"doc": [],
"short_name": "Аврора",
"status": "110"
},
"relations": {
"organizations_bank_accounts_rel": [
{
"attributes": {},
"ref": {
"id": "306c821f-3aaf-11ef-805b-d37c61cbe6d3",
"entityName": "bank_accounts"
}
}
]
},
"dataQuality": []
}
Пример запроса записи, которая содержит связь и классификатор:
GET http://universe-mdm-ea:8082/universe-backend/api/meta-data-driven/v1/data/industrial/4c7d8788-8225-11ee-b6df-d37c61cbe6d3
HTTP/1.1 200
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive
{
"etalonId": "4c7d8788-8225-11ee-b6df-d37c61cbe6d3",
"entityName": "industrial",
"externalKey": {
"id": "42545d10-8225-11ee-9295-b94aeb0b8e88",
"sourceSystem": "universe"
},
"createAt": "2023-11-13T13:05:21.896",
"updateAt": "2023-11-13T13:05:21.896",
"attributes": {
"tons": 0.0,
"mass": 1000.0,
"name": "Станок деревообрабатывающий",
"model": "FD-27638"
},
"relations": {
"svyaz": [
{
"attributes": {},
"ref": {
"id": "82a0495a-35d6-11ee-a909-d37c61cbe6d3",
"entityName": "persons"
}
}
]
},
"dataQuality": [],
"classifiers": {
"industrial_machine": {
"milling": {
"extensionProperties": {},
"attributes": {
"friq": 2000.0,
"aspir": 75.0,
"spindel": 30.0
},
"version": "industrial_machine"
}
},
"mtr": {
"trub": {
"extensionProperties": {},
"attributes": {},
"version": "mtr"
}
}
}
}
Пример запроса записи, которая содержит связь и комплексный атрибут:
GET http://universe-mdm-ea:8082/universe-backend/api/meta-data-driven/v1/data/organizations/12932d10-32d2-11ee-98d5-d37c61cbe6d3
HTTP/1.1 200
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive
{
"etalonId": "12932d10-32d2-11ee-98d5-d37c61cbe6d3",
"entityName": "organizations",
"externalKey": {
"id": "04f1cae0-32d2-11ee-9485-9dc19d9f8732",
"sourceSystem": "universe"
},
"createAt": "2023-08-04T14:20:34.407",
"updateAt": "2023-08-04T14:20:34.407",
"attributes": {
"okopf_id": "75502",
"okfs_name": "Совместная частная и иностранная собственность",
"individual_entrepreneur": true,
"full_name": "Общество с ограниченной ответственностью \"Ликар\"",
"Conmtacts": [
{
"contact_type": "02",
"contact_value": "+78655432654"
},
{
"contact_type": "07",
"contact_value": "likar@likar.com"
}
],
"status_name": "Регистрирующим органом принято решение о предстоящем исключении индивидуального предпринимателя из ЕГРИП (наличие оснований, предусмотренных подпунктом \"б\" пункта 2 статьи 22.4 Федерального закона от 08.08.2001 № 129-ФЗ \"О государственной регистрации юридических лиц и индивидуальных предпринимателей\")",
"doc": [
{
"type": "паспорт",
"numb": "235678"
}
],
"short_name": "ООО \"Ликар\"",
"okopf_name": "Благотворительные учреждения",
"okfs_id": "34",
"status": "111"
},
"relations": {
"organizations_addresses_rel": [
{
"attributes": {},
"ref": {
"id": "37784e69-530f-11ee-8ca2-d37c61cbe6d3",
"entityName": "addresses"
}
}
]
},
"dataQuality": []
}
Удаление записи¶
Метод используется для логического удаления записи. В качестве идентификатора используется etalonId.
Метод: DELETE
Путь запроса: {URL_стенда}/universe-backend/api/meta-data-driven/v1/data/{entity-name}/{etalon-id}
Пример запроса:
curl -X 'DELETE' \
'http://localhost:9081/universe-backend/api/meta-data-driven/v1/data/OKOPF/40c8610a-755f-11ed-9fbd-73aae866f4c6?wipe=false' \
-H 'accept: */*' \
-H 'Authorization: e555c773-c8e4-4698-95c7-73c8e4869865'
Обновление записи¶
Параметры запроса для patch = true
Формирование эталона записи в системе происходит в зависимости от весов систем-источников. В случае если веса равны, значения победившего атрибута становится равным значению самого свежего Origin. При обновлении записи, атрибуты обновляются информацией из системы bit.
В части интеграции, платформа предусматривает обновление только записи в целом. Указание значения по умолчанию в модели данных закладывает логику обработки входящих сообщений по интеграции. В таком случае, если логический атрибут не указан, то при расчете эталона будет выставлено значение по умолчанию.
Пример запроса:
curl -X 'POST' \
'http://10.21.0.176:8082/universe-backend/api/meta-data-driven/v1/data/test_check' \
-H 'accept: application/json' \
-H 'Authorization: ab605d3f-7110-48e9-a05d-3f7110c8e976' \
-H 'Content-Type: application/json' \
-d '{
"patch": true,
"sourceSystem": "bit",
"externalId": "test21214",
"attributes": {
"id": "test1111"
}
}'
Параметры запроса для patch = false
При patch = false атрибутам, которым не передалось значение в запросе - проставляется значение null. Значение установлено по умолчанию, из-за чего null меняется на него и становится самым новым атрибутом.
Если значение по умолчанию отсутствует, то передаваемый атрибут остается пустым и не участвует в консолидации. Таким образом, значение, которое вносили через UI остается самым новым и не заменяется на что-либо.
Пример запроса:
curl -X 'POST' \.
'http://10.21.0.176:8082/universe-backend/api/meta-data-driven/v1/data/test_check' \
-H 'accept: application/json' \
-H 'Authorization: ab605d3f-7110-48e9-a05d-3f7110c8e976' \
-H 'Content-Type: application/json' \
-d '{
"patch": false,
"sourceSystem": "bit",
"externalId": "test212",
"attributes": {
"id": "test111",
"id2": "test211"
}
}'
Уведомление состояния записи¶
Обновленный модуль уведомления отправляет состояние записи редактируемого периода актуальности.
Для сообщений meta-driven, об уведомлении вставки и удаления были добавлены поля:
"validFrom" - дата начала периода актуальности;
"validTo" - дата окончания периода актуальности.
Пример сообщения meta-driven:
{
"etalonId": "0219297e-86e9-11ef-bd97-5bd86fbfa823",
"entityName": "from",
"externalKey": {
"id": "fa5abd00-86e8-11ef-ba88-9915efe6d326",
"sourceSystem": "universe"
},
"validFrom": "2001-01-01T00:00:00.000",
"validTo": "2030-12-31T23:59:59.999",
"createAt": "2024-10-10T09:21:46.838",
"updateAt": "2024-10-10T09:21:46.838",
"attributes": {
"str": "настоящее"
},
"relations": {},
"dataQuality": [],
"classifiers": {}
}
Пример сообщения уведомления о вставке:
{
"id": "34234c71-d341-457f-b54a-a89e528b3681",
"entityName": "from",
"etalonId": "0219297e-86e9-11ef-bd97-5bd86fbfa823",
"originId": "128b36f9-86e9-11ef-bd97-5bd86fbfa823",
"timestamp": "2024-10-10T09:37:36.271967858",
"type": "UPDATE",
"attributes": {
"str": "настоящее"
},
"lookupLinkAttributes": null,
"relations": {},
"classifiers": {},
"recordChanges": null,
"relationsChanges": null,
"classificationsChanges": null,
"validFrom": "2001-01-01T00:00:00.000",
"validTo": "2030-12-31T23:59:59.999",
"draftOperation": false
}
Пример сообщения уведомления об удалении:
{
"id": "558afaa2-0ce7-4a77-958e-60d84720bec6",
"entityName": "from",
"etalonId": "0219297e-86e9-11ef-bd97-5bd86fbfa823",
"originId": "128b36f9-86e9-11ef-bd97-5bd86fbfa823",
"timestamp": "2024-10-10T09:40:50.759418981",
"type": "DELETE",
"validFrom": "2001-01-01T00:00:00.000",
"validTo": "2030-12-31T23:59:59.999",
"draftOperation": false
}