Обмен документами/задачами между независимыми компаниями используя RabbitMQ

Заказчик: ООО Аскона-Век
Исполнитель: DigitalAdvance LLC

Обмен документами/задачами между независимыми компаниями используя RabbitMQ

Группа компаний Аскона - лидер индустрии товаров для сна России, крупнейшая фабрика по производству анатомических матрасов в Восточной Европе. Askona входит в состав шведского концерна Hilding Anders Group - лидирующего производителя кроватей и матрасов в Европе и Азии. Концерн Hilding Anders присутствует на 27 Европейских и 13 азиатских рынках.
«Аскона» - это гарантия полноценного отдыха: каждый третий россиянин спит на матрасе Askona. Одна из причин этого – строгий контроль качества продукции в собственной лаборатории сна -  единственной в России испытательной лаборатории для мягкой мебели, сертифицированной ISO тестирующей по европейским стандартам. 

В 2011, 2013 и 2015 году, по результатам общенационального российского голосования, Askona удостоена самой уважаемой народной российской награды «Марка №1» в категории «матрасы для здорового сна», а в 2013 году и в категории «подушки для здорового сна».  Эта награда свидетельствует о доверии миллионов россиян к бренду Askona, что является гарантией успешного развития фабрики.

Цели и задачи проекта

Группа компаний Аскона в рамках своей деятельности взаимодействует с различными производителями товаров. В рамках этих взаимодействий существуют тесно интегрированные бизнес процессы. Например процесс создания нового продукта начинается в группе компаний, далее переходит в компанию производитель, а в последствии возвращается обратно уже в виде конкретного предложения и описания товара. Обычно эти взаимодействия происходят через обмен почтовыми сообщениями между менеджерами компаний.

В связи с тем что многие партнеры компании Асконы так же используют СЭД Директум была сформулирована цель разработать интеграционную шину данных и сделать разорванные процессы единым целым. 

Для реализации данной цели было выбрано СПО RabbitMQ.

Основной задачей было реализовать необходимые службы для бесшовной интеграции RabbitMQ и Directum.

Так же были разработаны необходимые маршруты которые использовали данный функционал.

Решение

Для взаимодействия двух и более систем Directum реализовано .NET приложение, представляющее  собой службу Windows (клиент) и библиотеку COM-объектов для Directum. Общение клиентов происходит по протоколу AMQP на платформе RabbitMQ, обеспечивающей обмен данными между приложениями в текстовом или бинарном формате без какой-либо их трансформации. Сообщения представляют  собой структурированные данные в формате JSON.

Выбор платформы RabbitMQ обусловлен её простотой и гибкостью одновременно. Следующие факторы стали ключевыми для принятия решения об использовании данной технологии:

  • Маршрутизация – возможность разграничивать данные на потоки (обмены, exchanges) и очереди  (queues). Решение может работать параллельно с несколькими клиентами, разграничивая потоки данных между ними.

  • Последовательность – возможность сохранения очередности передаваемых данных – приложение не приступит к обработке следующего входящего пакета, пока не закончится обработка текущего. Это важно для сохранения связей между объектами, будь это документ, задача, задание или что-либо еще. В решении на данном этапе используется одна общая очередь для входящих сообщений, при необходимости имеется возможность расширить функционал для разграничения пакетов на несколько очередей, выстраивая очередность по приоритету или иным факторам.

  • Надежность – платформа гарантирует доставку сообщения адресату. Пакет не затеряется в сети, не пропадёт в случае проблем на стороне платформы и даже в случае её перезагрузки. Такого уровня сложно достичь при использовании обычных web-сервисов, которые рассматривались в качестве альтернативного способа обмена данными.

Итого в состав решения входят:

  1. Сервер RabbitMQ в качестве транспорта
  2. Служба Windows на платформе .NET для обработки входящих сообщений
  3. Библиотека COM-объектов для отправки сообщений из Directum

Формат сообщений

В качестве формата передаваемых данных выбран один из самых простых и популярных на данный момент формат JSON. Пакет представляет собой определенную структуру, содержащую в себе метаданные и список команд, которые необходимо выполнить в Directum на стороне клиента.

Метаданные

Каждый пакет содержит в себе служебную информацию, которая необходима только для правильной обработки сообщения и никакой ценности для Directum не несёт. В состав таких данных входит уникальный идентификатор сообщения, счетчик попыток обработки пакета, служебное сообщение, описание ошибки и пр.

В основном, эти данные необходимы для идентификации сообщения и обработки ситуаций, когда по той или иной причине выполнение указанных в нём действий завершаются ошибкой – в таких случаях пакет перемещается в отдельную очередь, выжидает некоторое время и возвращается в основную, пытаясь снова выполнить указанные действия. Если при очередной ошибке счетчик попыток достигает максимального значения, пакет перемещается в очередь «проблемных» и обрабатывается отдельными инструментами. Выбор этих инструментов остается за вами – вы можете обрабатывать очередь проблемных пакетов и, например, отправлять их на почту специалисту для выяснения причин, или транслировать в систему обработки журналов событий для дальнейшей обработки…

Действия

Поступление сообщения означает необходимость выполнения каких-либо действий в системе Directum: создание документа, создание задачи и выполнение задания – всё это можно выполнить на уровне платформы Directum с помощью предустановленных команд решения.

Каждое действие заранее реализовано и имеет свой уникальный идентификатор с набором параметров. Например, для создания задачи потребуется указать код типового маршрута, параметры задачи и его свойства (например, тему задачу) и данные вложения. Для создания документа или выполнения задания набор параметров будет отличаться.

На текущий момент реализованы базовые методы для работы с Directum:

  • Создание документа
  • Импортирование версии документа
  • Создание задачи
  • Редактирование задачи
  • Получение состояния задачи
  • Выполнение задания

На будущее запланировано увеличение возможностей работы действий и их оптимизация для более простой и прозрачной работы с ними.

Обратные действия

В пакете сообщения  предусмотрены обратные действия (callback`s), которые будут выполнены на стороне отправителя после обработки пакета целевым получателем. Данный функционал очень полезен в тех случаях, когда мы желаем узнать о результатах выполнения каких-либо действий, например, получить идентификатор созданного документа в целевой системе – такие механизмы необходимы для синхронизации данных между системами.

Передача документов

Решение позволяет передавать документы из одной системы в другую различными способами – вложением при создании задачи, отдельным документом или импортированием в существующий документ. В состав документа входят все реквизиты карточки типа документа и его тело – версия документа, закодированная по стандарту Base64.

Сложность заключается в сопоставлении реквизитов между двумя системами – наименование полей, их тип и наличие практически никогда не совпадут в двух и более различных системах Directum. Данную проблему никак не решить, кроме как ручным сопоставлением и контролем реквизитов с каждой из сторон участников обмена.

Синхронизация данных сопоставления между клиентами должна происходить быстро и просто, поэтому было решено хранить их в СУБД SQLite, не помещая в справочники Directum. При таком подходе достаточно передать обновленный файл базы данных от одного участника обмена другому с описанием изменений.

При обработке сообщения  производится сопоставление реквизитов системы-источника и системы-получателя по типу, виду документа и целевой системе, в результате которого документ будет создан с правильными реквизитами.

На будущее запланирован механизм централизованной СУБД и, возможно, веб-интерфейс для более цивилизованного редактирования схем сопоставления.

Служба обработки сообщений

Directum не имеет достаточных возможностей для работы с протоколом AMQP и обработки входящих сообщений, поэтому эту роль выполняет отдельное приложение на платформе .NET, работающая в качестве службы Windows.

Данная служба подключена к транспорту RabbitMQ и ожидает поступления сообщений по указанному узлу обмена в указанную очередь сообщений. Как только поступит новое сообщение, производится попытка его обработки – выполнения всех указанных в сообщении действий. После успешного выполнения каждого действия, оно помечается обработанным и в случае возникновения ошибки на поздних этапах повторно выполнено не будет.

При выполнении действий приложение общается с платформой Directum с помощью его COM-объектов из состава библиотек SBRte и SBLogon.

В случае успешного выполнения всех действий сообщение помечается прочитанным и удаляется из очереди, в противном же случае пакет отправляется в очередь на повторную обработку.

Библиотека COM-объектов

Для формирования и отправки сообщений из системы Directum предусмотрена библиотека COM-объектов, которая при необходимости подключается в расчетах системы и выполняет необходимые действия. Библиотека имеет методы формирования пакетов сообщений и их отправки  в транспорт RabbitMQ, что позволяет нескольким никак несвязанным между собой системам Directum вести диалог между собой.

Схема работы

Ниже приведена приблизительная схема работы решения на примере обмена между двумя системами Directum с помощью одного канала обмена и одиночными очередями сообщений.

Пример реализации

Рассмотрим работу решения на примере. Допустим, имеется необходимость согласования какого-либо документа в удаленной системе Directum наших партнёров – поставим себе задачу отправить документ, получить результат согласования и ознакомить ответственных лиц рассылкой уведомлений в собственной системе Directum.

Примерная схема типовых маршрутов:

Всё взаимодействие с внешней системой производится в блоках №2.

Создание задачи во внешней системе

В событии «Создание заданий» системы-отправителя Directum обращается к библиотеке COM-объектов решения и формирует пакет с действиями создания задачи и документа.

Чтобы внешняя система смогла сообщить нам, что задача выполнена, передадим в качестве параметров идентификатор текущей задачи и задания.

Чтобы внешняя система смогла импортировать подписанный документ в оригинальный, передадим в качестве параметров идентификатор документа.

 Для того  чтобы иметь возможность отслеживания состояния задачи в удаленной системе добавляем обратное действие на обновление текущей задачи, которое запишет в параметр идентификатор задачи внешней системы.

// Получение объекта

bus = CreateObject("Directum.BusDriver")

 

// Создание пакета сообщения

message = bus.CreateMessage()

 

// Создание действия на создание задачи

action = message.ActionCreateTask()

 

// Возьмем документ из вложения для отправки его в удаленную систему

documentID = ТМПолучитьПараметрЗадачи('DocID')

document = edocuments.GetObjectByID(documentID)

 

// Список параметров задачи

job = createdJobs.Value

 

ex1mail = ТМПолучитьПараметрЗадачи('Executor1Mail')

author = object.Requisites("Author").DisplayText

 

options = bus.CreateList()

options.Add("RemoteTaskID"; object.ID)       // ид текущего задачи

options.Add("RemoteJobID"; job.ID)               // ид текущего задания

options.Add("RemoteDocID"; documentID)  // ид согласуемого документа

options.Add("RemoteTaskText"; ТМПолучитьПараметрЗадачи('RemoteTaskTextToTD'))      // тело задачи

 

// Список реквизитов задачи

properties = bus.CreateList()

properties.Add("Subject"; "Согласование " & document.SYSREQ_EDOC_NAME)

 

// Создание задачи

action.AddTask("ТМ_2"; options; properties)

 

// Добавление вложения в задачу

action.AddDocument(document)

 

// Создание обратного действие (callback-функция) на обновление текущей задачи

callback = message.ActionUpdateTask(true)

 

// Список параметры для обновления текущей задачи

params = bus.CreateList()

params.Add("RemoteTaskID"; "Result.TaskID") // получим и запомним ID удаленной задачи

 

// Добавим действие на обновление параметров задачи

callback.SetTaskParameter(work.ID; params)

 

// Отправим сообщение

message.Send()

 

Во внешней системе будет создана задача по типовому маршруту с кодом  «ТМ_2» и параметрами RemoteTaskID, RemoteJobID, RemoteDocID. Буден создан и вложен в задачу переданный документ.

Созданная задача запускается автоматически и отправляет результат согласования после принятия решения.

Отправка результата из внешней системы

После принятия решения по документу во внешней системе производится формирование пакета с действиями обновления документа (импорт подписанной версии) и выполнения задания.

Идентификатор оригинального документа нам известен – он сохранен в параметре RemoteDocID.

Идентификатор задания, которое нужно выполнить, нам известен – он сохранен в параметре RemoteJobID.

Сформируем пакет и отправим его:

// Получение объекта

bus = CreateObject("Directum.BusDriver")

 

// Создание пакета сообщения

message = bus.CreateMessage()

 

// Добавим действин на обновление задачи

remoteTaskID = ТМПолучитьПараметрЗадачи("RemoteTaskID")

 

action = message.ActionUpdateTask(false)

 

params = bus.CreateList()

params.Add("RemoteTaskText"; object.GetFullText(false))

 

action.SetTaskParameter(remoteTaskID; params)

 

// Добавим действие на обновление документа текущей версией

attachments : IAttachmentList = object.GetAttachments(false)

attachments.Reset

documentID = attachments.Value.ObjectInfo.ID

document = edocuments.GetObjectByID(documentID)

 

remoteDocID = ТМПолучитьПараметрЗадачи("RemoteDocID")

 

action2 = message.ActionImportDocument(false)

action2.ImportDocument(remoteDocID; document)

 

// Добавим действие на выполнение задания

remoteJobID = ТМПолучитьПараметрЗадачи("RemoteJobID")

executeCode = ТМПолучитьПараметрЗадачи("ResultCode")

 

comment = ''

if (executeCode == 'Y')

  comment = 'Документ согласован'

else

  comment = 'Документ не согласован'

endif

 

action3 = message.ActionExecuteJob(false)

action3.ExecuteJob(remoteJobID; comment; executeCode)

 

// Отправим сообщение

ret = message.Send()

После обработки сообщения системой указанное задание будет выполнено указанным вариантом выполнения, в документ будет импортирована согласованная версия документ и в текст задачи пропишется вся история согласования из внешней системы.

Результаты

В результате проекта были реализованы необходимые службы и создан сквозной бизнес-процесс. Данная работа позволила существенно сократить время взаимодействия между менеджерами компаний, сделать их работу более прозрачной и контролируемой. 

Перспективы

Используя механизм очередей реализованный с помощью RabbitMQ СЭД Directum может быть легко интегрирован с любым корпоративным программным обеспечением (ERP, CRM, сайт). 

Номинация: Forum
Организация: ООО «АСКОНА-ВЕК»
2
Подписаться
Опубликовано:
7 декабря 2018 в 14:21
  • 6

Комментарии

Мощное решение!

Вопросы на уточнение:

1. Существует механизм DCI (https://club.directum.ru/webhelp/directum/5.6/index.html?collection_dci.htm). Решает те же задачи, чем не подошло решение?

2. Сколько организаций участвует в межсистемном взаимодействии? На каких версиях DIRECTUM?

3. В исходном коде задается код ТМ сторонней системы. Как решаете вопрос об именовании разработки в сторонней системе, договариваетесь с разработчиками партнеров?

Вы пишете: "На будущее запланирован механизм централизованной СУБД и, возможно, веб-интерфейс для более цивилизованного редактирования схем сопоставления." Зачем тогда прикрутили сюда RabbitMQ, чтобы попробовать технологию?

Юрий Кузнецов

10 декабря в 16:32

Вы пишете: "На будущее запланирован механизм централизованной СУБД и, возможно, веб-интерфейс для более цивилизованного редактирования схем сопоставления." Зачем тогда прикрутили сюда RabbitMQ, чтобы попробовать технологию?

---------------

Централизованная СУБД запланирована для хранения конфигурации, а не для обмена через неё.

В конфигурации хранятся правила сопоставления карточек документов и их реквизитов и прочие системные настройки.

Сергей Рождественский: обновлено 10.12.2018 в 17:08

Наталия Соколова

10 декабря в 15:18

Мощное решение!

Вопросы на уточнение:

1. Существует механизм DCI (https://club.directum.ru/webhelp/directum/5.6/index.html?collection_dci.htm). Решает те же задачи, чем не подошло решение?

2. Сколько организаций участвует в межсистемном взаимодействии? На каких версиях DIRECTUM?

3. В исходном коде задается код ТМ сторонней системы. Как решаете вопрос об именовании разработки в сторонней системе, договариваетесь с разработчиками партнеров?

------------------------------

  1. В ранних версиях Directum данного компонента не было (подобный компонент DICS не устраивал заказчика).

  2. В обмене участвует две системы с версиями 5.0 и 5.4.1. Поддерживается произвольное количество одновременно работающих систем – хоть 2, хоть 50. Версии значения так же не имеют.

  3. Всё взаимодействие с система обговаривается и согласовывается обеими сторонами, при каких-либо изменениях одна сторона обязательно уведомляет другую – увы, уйти от этого сложно.

1. А на чем пишутся callback'и?

2. А как при таком раскладе сделать интеграцию с двумя системами с разной разработкой, как делить базу данных между ними? Я про базу данных в котором прописано соответствие реквизитов документов.

 

  1. Callback`и это те же самые действия, которые мы отправляем в целевую систему. На данный момент они являются предопределенными и зашиты в службу обмена сообщениями, которая работает на платформе .Net, которая взаимодействует с объектной моделью Directum.
  2. Таблица соответствий на данный момент является прототипом и имеет самый базовый вид, для соответствия типов карточек, например, используется таблица вида [SystemFrom, SystemTo, CardTo, CardFrom] (образно), где для каждой пары SystemFrom/SystemTo задается соответствие. 

 

-----------------------------------------------

 

Сергей Камышев

11 декабря в 12:35

1. А на чем пишутся callback'и?

2. А как при таком раскладе сделать интеграцию с двумя системами с разной разработкой, как делить базу данных между ними? Я про базу данных в котором прописано соответствие реквизитов документов.

Авторизуйтесь, чтобы написать комментарий