Интеграция KafkaSync

Утилита забирает сообщения из брокера Kafka из определённых очередей (топиков) и создаёт структуру в Vitro MP на основе этих данных.

Обрабатываемые топики

ИСУП

  • isup.project-1 — сообщения о проектах системы
  • isup.constructions-object-1 — объекты строительства системы
  • isup.construction-object-type-1 — (справочник) типы объектов строительства
  • isup.place-of-implementation-1 — (справочник) места реализации
  • isup.building-unit-1 — корпусы

ФСК Проектирование

  • kup.schedule-1 — графики
  • kup.schedule-responsibles-1 — ответственные у графиков
  • kup.performers-groups-1 — группы исполнителей
  • kup.direction-1 — направления ЦГИП
  • kup.task-1 — задачи

Исходящие (Vitro → Kafka)

  • vitro.event-status — смена статуса альбома (раздел 5)
  • vitro.status-list — справочник статусов (раздел 5.1)

1. Описание интеграции

ИСУП предоставляет сообщения о верхнеуровневой структуре: Проект → Объект строительства → Корпус.

Сущности распространяются на списки:

  • Реестр проектов
  • Файлы

В реестре проектов сохраняется полная иерархия ИСУП. В файловой структуре создаются проект и корпус; корпус размещается непосредственно под проектом. Промежуточный элемент «Очередь» и связи через список «Связи» больше не используются.

Связь корпуса с проектом в файлах обеспечивается полем proekt_id_isup на карточке корпуса в реестре (заполняется вычислением, см. раздел 7.3).

ФСК Проектирование предоставляет сущности ниже ТЭ «Корпус»: Стадия, Комплект, Раздел, Альбом, ИЗМ и другие типы из KupMap.

Связь ИСУП и ФСК Проектирование — через справочник «Графики KUP» (kup.direction-1).

При создании корпуса в системе настроена автоматизация на разворачивание шаблона Vitro.

KafkaSync записывает числовые id ИСУП и иерархию parent_id. Guid-лукапы заполняются в Vitro через вычисления и автоматизации (раздел 7).

2. Требования к системе

2.1. Атрибуты

НазваниеСистемное имяТипОписание
ID ИСУПid_isupIntegerчисловой идентификатор в ИСУП
GUID 1Cguid_1cstringидентификатор из 1С
Короткое имяshort_namestringкороткое имя
ОписаниеdescriptionNoteполное описание
Проект (карточка)project_cardLookupлукап на карточку проекта
Карточка корпусаbuilding_lookupLookupлукап на карточку корпуса
ID проекта ИСУПproekt_id_isupIntegerid_isup проекта для размещения корпуса в файлах
Тип объекта (значение ИСУП)object_type_isup_valueIntegerчисловой id типа объекта из Kafka
Тип объекта строительстваconstruction_object_typeLookupлукап на справочник типов
Место реализации (значение)mesto_realizacii_isup_valueIntegerчисловой id места реализации
Место реализацииmesto_realizaciiLookupлукап на справочник мест
GUID KUPguid_kupstringидентификатор ФСКП
ИД КУПshort_name_kupstringKey в ФСКП
ИД Шаблона КУПtemplate_task_idstringшаблон задачи ФСКП
Сортировка КУПorder_kupstringпорядок элемента
Тип KUPtype_kupstringтип задачи из Kafka
Path GUID KUPpath_guid_kupstringуникальный путь элемента
Schedule ID KUPschedule_id_kupstringидентификатор графика
Основной графикis_primary_kupbooleanфлаг основного графика
Полное названиеfull_nameNoteполное имя
Направление ЦГИПdivision_tsgip_attLookupнаправление ЦГИП
ГИПchief_project_engineerLookupна корпусе
Помощник ГИПаchief_engineer_assistantLookupна корпусе
ГИП наружных сетейchief_project_engineer_site_utilitiesLookupна корпусе
ГИП заказчикаgip_customerLookupна корпусе
Руководитель проектаproject_managerLookupна корпусе
ОтветственныйresponsibleLookupна задачах ФСКП
Лист согласованияapproval_user_listLookupисполнители
Наличие внешнего проектировщикаexternal_designer_conditionLookupтип исполнителя
Сообщение Kafkamessage_kafkaNoteтекст сообщения
Топик Kafkatopic_kafkastringтопик
Ошибка Kafkaerror_kafkastringошибка обработки
Обработано Kafkasuccess_kafkabooleanфлаг обработки

2.2. Типы элементов

Тип элементаАтрибуты
Карточка проектаid_isup, short_name, description, guid_1c, mesto_realizacii_isup_value, mesto_realizacii
Карточка объекта строительстваid_isup, guid_1c, object_type_isup_value, construction_object_type
Карточка корпусаid_isup, proekt_id_isup, construction_object_type
Место реализацииid_isup
Тип объекта строительстваid_isup
Проектid_isup, guid_1c, short_name, description, project_card, mesto_realizacii
Корпусid_isup, building_lookup, construction_object_type, chief_project_engineer, chief_engineer_assistant, chief_project_engineer_site_utilities, gip_customer, project_manager
Стадия / Комплект / Раздел / Альбом / ИЗМguid_kup, order_kup, short_name_kup, template_task_id, type_kup, path_guid_kup, schedule_id_kup, full_name
Альбом+ division_tsgip_att, responsible, approval_user_list, external_designer_condition
Задача план-графикаid_isup
Карточка направления ЦГИПguid_kup
График KUPguid_kup, id_isup, is_primary_kup
Сообщение Kafkamessage_kafka, topic_kafka, error_kafka, success_kafka

2.3. Списки

НазваниеТипы элементов
ФайлыАльбом, Комплект, Раздел, Стадия, Корпус, Проект, ИЗМ
Реестр проектовКарточка проекта, Карточка объекта строительства, Карточка корпуса
Типы объектов строительстваТип объекта строительства
Места реализацииМесто реализации
Справочник направлений ЦГИПКарточка направления ЦГИП
Графики KUPГрафик KUP
Импорт из KafkaСообщение Kafka
Экспорт в KafkaСообщение Kafka
Черный список проектов ИСУПКарточка проекта, Карточка объекта строительства
Черный список элементов ФСКППапка

3. Настройка config.json

Файл в корне с исполняемым файлом. Пример для vitro.dev FSK без паролей:

{
  "WebUrl": "https://vitro.dev.fsk.ru",
  "Login": "admin",
  "Password": "password",
  "LibraryListId": "966e62c5-a803-49a0-a1be-e680d130c481",
  "LibraryParentId": "5da4709f-3c94-4a82-b335-800117096b46",
  "ReferenceListId": "5b911635-5f2a-4049-926b-60ec11be3d17",
  "ObjectTypeListId": "1a0671ac-6ffd-4c2a-ac83-177c4902377d",
  "PlaceImplListId": "fcdecebd-4a57-41ed-8265-9c3d4d586b8b",
  "KafkaMessageContentTypeId": "c3629456-3773-49b8-8a58-d4198e77ad8e",
  "KafkaExportListId": "d244569a-fb9b-46f9-8a04-925c8baba2bb",
  "KafkaImportListId": "9955d107-98e8-42e9-8cd6-19817764cfd3",
  "ObjectTypeContentTypeId": "c8988a65-df34-4f60-88fd-90d23965c1fe",
  "PlaceImplContentTypeId": "4002a57c-d5ad-42e9-a7f5-531c5d3ad99e",
  "ProjectReferenceContentTypeId": "74546a61-799e-46aa-9a79-7f7661bb707f",
  "ProjectContentTypeId": "540ff572-4a29-4d8e-8dfb-8eda093c583a",
  "ObjectReferenceContentTypeId": "2ecac8b4-e621-400d-a63f-d456f4820efb",
  "BuildingReferenceContentTypeId": "7175d8a2-2253-4172-b68b-150b823d855c",
  "BuildingContentTypeId": "5c16ee47-fe94-4fc2-bd68-32ce0beb2a68",
  "PerformerGroupContentTypeId": "7a5850e5-c2f4-4121-8ed4-450e3f0b4439",
  "PerformerGroupListId": "daf3fd57-a7a4-4524-ae87-a359e6ffe082",
  "ScheduleContentTypeId": "8e825548-5786-4aa5-b9af-8ad5ac157819",
  "ScheduleListId": "e3d0f0ac-cc64-49b0-a06e-774fdc618ea2",
  "DirectionContentTypeId": "9846503c-0b8a-4405-9d10-44f672f83fd5",
  "DirectionListId": "66ec35fd-a050-45b6-87b2-61d65115cf90",
  "IsupBlackListId": "af70989d-ca8f-450e-9422-6f323e9fcf65",
  "KupBlackListId": "e77e04d3-f830-4b97-9d3a-d7cb39bd76b6",
  "KupMap": {
    "STAGE": "64a15f4c-083e-420b-b54e-fc75d44f31b7",
    "SET": "78109552-37b6-4d87-b57f-bf11867bbaa9",
    "SECTION": "ae453be5-c213-4ec6-b0ca-4efa2f9a98b7",
    "ALBUM": "28a48961-35e0-43ae-ad6b-8f159cfd7202",
    "IZM": "40a444c3-0f78-407f-8dba-d79ab0db2583",
    "APR": "39c299a7-8c85-4c5c-811f-b654e2eb3099",
    "STAGE_P": "da4a52ff-ceda-4b5e-b593-5a6339b50233",
    "AGR": "0ae0d7cb-b8a2-43fe-8e40-9841c016adad",
    "AGO": "f971344d-2e33-4d3a-8c84-cd942db81096",
    "PSO": "b4a23642-bc6b-4aa2-97fb-b53631c732bd",
    "FACTORY_PREORDER": "75e05071-cf52-4068-963f-622e66ecf7c8",
    "RD": "de5012af-fa90-443e-b79b-cf2f56e0b5ed",
    "CORRECTION_P": "8f586139-8987-4572-bae7-281d9d31acac",
    "IEMD": "78109552-37b6-4d87-b57f-bf11867bbaa9",
    "ITERATION_SET": "09ad2c16-6047-4dfb-8274-6c4a5f1edbe5",
    "CORRECTION_P_ZOS": "09ad2c16-6047-4dfb-8274-6c4a5f1edbe5"
  },
  "PerformerTypeMap": {
    "CONTRACTOR": "67e87ece-0994-4bf0-98d2-8837f6f87abf"
  },
  "KafkaConfig": {
    "GroupId": "vitro.test",
    "BootstrapServers": "kafka.k8s-dev.fsk.ru:9094",
    "SaslUsername": "vitro",
    "SaslPassword": "password",
    "SecurityProtocol": "SaslPlaintext"
  }
}

4. Настройка времени запуска утилиты

На усмотрение администраторов. Пример: https://portal.vitrocad.ru/pages/viewpage.action?pageId=23659062

5. Обратная интеграция. Настройка автоматизации

  • Тип элемента: Альбом
  • Атрибут триггера: Статус
  • Действие: Вызов внешнего сервиса

Условия: IsNotNull(This("GUID КУП"))

Действия:

Format('{0}/api/automation/post?baseUrl={0}/api/item/update&param=[{"list_id":"d244569a-fb9b-46f9-8a04-925c8baba2bb","content_type_id":"c3629456-3773-49b8-8a58-d4198e77ad8e",
"success_kafka":false,"topic_kafka":"vitro.event-status",
"message_kafka":"{\\"update_date\\":\\"{1}\\",\\"guid_kup\\":\\"{2}\\",\\"template_task_guid\\":\\"{3}\\",\\"key\\":\\"{4}\\",\\"document_status\\":\\"{5}\\",\\"building_id\\":\\"{6}\\",\\"type\\":\\"PDF\\",\\"change_number\\":{7} }"}]',
Cfg('Site.PortalUrl'), DateTime(This('Изменен'), 'yyyy-MM-ddTHH:mm:ss.fffZ'), This('GUID КУП'), This('ИД Шаблона КУП'), This('ИД КУП'), Id(This('Статус')), Field(Parent('Корпус'),'id_isup'), This('Номер ИЗМа'))

При срабатывании создаётся элемент в «Экспорт в Kafka» с success_kafka = false. Утилита отправляет его в vitro.event-status.

5.1. Экспорт справочника статусов

Утилита автоматически экспортирует изменённые статусы в vitro.status-list. Автоматизация не требуется. Формат: {"status":"{название}","id":"{guid}"}

6. Черный список проектов ИСУП

Проекты и объекты строительства, которые не будут созданы или обновлены.

Добавление

  1. Создать «Карточку проекта» с id_isup.
  2. Если проект уже синхронизирован — удалить вручную.
  3. Объекты добавляются утилитой автоматически.

Удаление

В «Черном списке»: записать id_isup объектов, удалить объекты и проект.

В «Импорт из Kafka»: для сообщений с BlackListException проставить success_kafka = false.

Шаг «восстановление очередей» больше не актуален.

6.1. Черный список элементов ФСКП

Список KupBlackListId. Элементы с неизвестным type из kup.task-1 или дочерние заблокированного родителя попадают сюда автоматически.

7. Настройка Vitro для работы интеграции

Инструкция первичной настройки. Предполагается, что базовые списки заведены, но изменения по новой схеме ИСУП (без очередей) ещё не выполнены.

7.1. Добавить атрибуты в систему

НазваниеСистемное имяТип
Место реализацииmesto_realizaciiLookup → справочник мест реализации
Место реализации (значение ИСУП)mesto_realizacii_isup_valueInteger
Тип объекта (значение ИСУП)object_type_isup_valueInteger
ID проекта ИСУПproekt_id_isupInteger
Тип объекта строительстваconstruction_object_typeLookup → типы объектов
Проект (карточка)project_cardLookup → реестр проектов
Карточка корпусаbuilding_lookupLookup → реестр проектов

7.2. Привязать атрибуты к типам элементов

Тип элементаДобавить атрибуты
Карточка проектаmesto_realizacii_isup_value, mesto_realizacii
Карточка объекта строительстваobject_type_isup_value, construction_object_type
Карточка корпусаproekt_id_isup, construction_object_type
Проект (Файлы)project_card, mesto_realizacii
Корпус (Файлы)building_lookup, construction_object_type

7.3. Настроить вычисления

Формулы вычисления (не автоматизации). Имена типов в Parent('…') — как в UI.

Тип элементаАтрибутФормула
Карточка корпусаproekt_id_isupField(Parent('Карточка проекта'), 'id_isup')
Карточка корпусаconstruction_object_typeField(Parent("Карточка объекта строительства"), "construction_object_type")
Корпус (Файлы)construction_object_typeField(This("building_lookup"), "construction_object_type")
Проект (Файлы)mesto_realizaciiField(This('project_card'), 'mesto_realizacii')

7.4. Настроить автоматизации

Остальные лукапы — записи в списке «Автоматизация». Общий алгоритм:

  1. Создать элемент в списке «Автоматизация».
  2. Триггер: «Изменено значение атрибута» — выбрать тип элемента и атрибут-триггер.
  3. Условие: формула, возвращающая true (поле «Формула» у условия).
  4. Действие: «Установить значение атрибута» — целевой атрибут и формула значения.
  • GUID списков и типов — из config.json целевой среды.

Таблица автоматизаций:

НазваниеТип элементаТип действияТриггерАтрибут действия
1Проект → project_cardПроект (Файлы)Установить значение атрибутаid_isupproject_card
2Карточка проекта → mesto_realizaciiКарточка проектаУстановить значение атрибутаmesto_realizacii_isup_valuemesto_realizacii
3Карточка объекта → construction_object_typeКарточка объекта строительстваУстановить значение атрибутаobject_type_isup_valueconstruction_object_type
4Корпус → building_lookupКорпус (Файлы)Установить значение атрибутаid_isupbuilding_lookup

Автоматизация 1. Проект → project_card

Условие:

Count(GetList(
  "5b911635-5f2a-4049-926b-60ec11be3d17",
  "i => i.ContentTypeId == Guid(\"74546a61-799e-46aa-9a79-7f7661bb707f\") && i.GetValueAsInt(\"id_isup\") == " + Str(This("id_isup")),
  true)) == 1

Формула действия:

Join("", Select(GetList(
  "5b911635-5f2a-4049-926b-60ec11be3d17",
  "i => i.ContentTypeId == Guid(\"74546a61-799e-46aa-9a79-7f7661bb707f\") && i.GetValueAsInt(\"id_isup\") == " + Str(This("id_isup")),
  true), "Str(Id())"))

Автоматизация 2. Карточка проекта → mesto_realizacii

Условие:

Count(GetList(
  "fcdecebd-4a57-41ed-8265-9c3d4d586b8b",
  "i => i.ContentTypeId == Guid(\"4002a57c-d5ad-42e9-a7f5-531c5d3ad99e\") && i.GetValueAsInt(\"id_isup\") == " + Str(This("mesto_realizacii_isup_value")),
  false)) == 1

Формула действия:

Join("", Select(GetList(
  "fcdecebd-4a57-41ed-8265-9c3d4d586b8b",
  "i => i.ContentTypeId == Guid(\"4002a57c-d5ad-42e9-a7f5-531c5d3ad99e\") && i.GetValueAsInt(\"id_isup\") == " + Str(This("mesto_realizacii_isup_value")),
  false), "Str(Id())"))

Автоматизация 3. Карточка объекта → construction_object_type

Условие:

Count(GetList(
  "1a0671ac-6ffd-4c2a-ac83-177c4902377d",
  "i => i.ContentTypeId == Guid(\"c8988a65-df34-4f60-88fd-90d23965c1fe\") && i.GetValueAsInt(\"id_isup\") == " + Str(This("object_type_isup_value")),
  false)) == 1

Формула действия:

Join("", Select(GetList(
  "1a0671ac-6ffd-4c2a-ac83-177c4902377d",
  "i => i.ContentTypeId == Guid(\"c8988a65-df34-4f60-88fd-90d23965c1fe\") && i.GetValueAsInt(\"id_isup\") == " + Str(This("object_type_isup_value")),
  false), "Str(Id())"))

Автоматизация 4. Корпус → building_lookup

Условие:

Count(GetList(
  "5b911635-5f2a-4049-926b-60ec11be3d17",
  "i => i.ContentTypeId == Guid(\"7175d8a2-2253-4172-b68b-150b823d855c\") && i.GetValueAsInt(\"id_isup\") == " + Str(This("id_isup")),
  true)) == 1

Формула действия:

Join("", Select(GetList(
  "5b911635-5f2a-4049-926b-60ec11be3d17",
  "i => i.ContentTypeId == Guid(\"7175d8a2-2253-4172-b68b-150b823d855c\") && i.GetValueAsInt(\"id_isup\") == " + Str(This("id_isup")),
  true), "Str(Id())"))
  • No labels