Описание ecos-edi-ftps-lib

1. Цель либы

Либа создана для обмена EDI-сообщениями с контрагентами через какой-то FTP-сервер.

Общий принцип работы:

Контрагент кладет в определенную папку сообщение, либа при активированной синхронизации раз в какое-то время производит рекурсивный обход по папкам на сервере и находит новые документы (подробнее в п.4).

Отправка сообщений контрагенту происходит наоборот: В специальную папку либа кладет EDI-сообщение и когда то в будущем контрагент его заберет (подробнее в п.3).

2. Настройка интеграции

Для настройки, как и для любой интеграции ЭДО - необходимо создать ecos-credentials, ecos-data-sources, edi-box и ecos-sync сущности.

2.1. Создание ecos-credentials сущности

Тут все стандартно, создаем через журнал ecos-credentials запись, в которой указываем логин и пароль для подключения к FTP-серверу.

2.2. Создание ecos-data-sources сущности

Создавать необходимо сущность “FTP Data source“. Поля id и name не важны.

../../_images/ecos-edi-ftps-lib_1.png

Важны host, port и protocol, где:

host - путь к серверу. В моем случае - локальный хост.

port - порт по которому ходим к серверу. Стандарт обычно 21.

protocol - на данный момент поддерживается FTP или FTPS.

2.3. Создание edi-box сущности

Создаем сущность “FTP box”.

../../_images/ecos-edi-ftps-lib_2.png

Самая основная часть конфигурации именно тут. Тут существует 3 раздела. В верхнем разделе:

  • id - указываем любой (или оставляем пустым и оно само сгенерится при создании).

  • name - любое человеко-читаемое название для этого ящика.

  • URL- указываем созданный в 2.2 датасорс.

  • Credentials - указываем созданные в 2.1 креды.

В разделе Box configuration - заполняем идентификатор номером GLN организации, от имени которой происходит разбор EDI-сообщений.

Раздел Other:

  • Outbound documents folder path template - шаблон пути, по которому будут отправляться исходящие сообщения. Подробнее в п.3.

  • Inbound documents folder path template - шаблон пути, по которому будут получаться входящие сообщения. Подробнее в п.4.

  • Search documents in subdirectories - чекбокс с говорящим названием, который означает, что мы должны искать документы не только в папке полностью соответствующей конфигу выше, но и в поддиректориях.

  • Inbound processing policy - выбор из вариантов обработки входящих сообщений. Существует 2 варианта - MOVE_AFTER_PROCESSING и DELETE_ON_SUCCESS. Подробнее в п.4.

  • Inbound documents success folder path template - (используется только при MOVE_AFTER_PROCESSING) - папка куда складываются документы, которые были успешно обработаны.

  • Inbound documents error folder path template - (используется только при MOVE_AFTER_PROCESSING) - папка, куда складываются документы, в результате обработки которых получили ошибку.

2.4. Создание ecos-sync сущности

Ничем не отличается от остальных интеграций, можно посмотреть в общей статье: Настройка получения событий с ящиком Контур_Диадок

Указывать, конечно, сущность edi-box из п.2.3.

3. Принципы работы при отправке сообщений

Вся либа построена на том, что мы указываем относительные пути в конфигурации. Переменные для подстановки приходят из структуры EdiXmlRequest из либы ecos-edi-commons Описание работы интеграции :ref:

Эта структура состоит из следующих полей:

private OurId ourId;
private CounterpartyId counterpartyId;
private EdiXml ediXml;
private ObjectData data;

где:

  • ourId маппится для подстановки в виде ourId.key_from_attributes (OurId состоит из ObjectData. Это означает, что если в ObjectData находится 2 значения с ключами key1 и key2, то в шаблоне можем использовать значения по следующим ключам: ourId.key1 и vourId.key2``).

  • counterpartyId маппится для подстановки в виде counterpartyId.key_from_attributes (аналогично ourId).

  • ediXml маппится всего в 2 значения: document.type, где могут быть значения ORDERS, ORDRSP, DESADV, RECADV, etc и в document.lowerType, где могут быть значения orders, ordrsp, desadv, recadv, etc.

  • data - полностью маппится в виде addInfo.key.

Для заполнения data - можно на проектах расширить интерфейс FtpCustomAddInfoProvider и зарегистрировать его в бине FtpCustomAddInfoProviderRegistry. Таким образом, можно на любом проекте кастомную логику по определению путей сделать. Пример шаблонов:

/${addInfo.counterparty.esk}_S4TEST/OUTBOUND/${document.type}

Это означает, что если в структуре data содержится значение 123456 по ключу counterparty.esk и ediXml.ediDocumentType содержит значение ORDERS, то данное сообщение отправится в следующую папку:

/123456_S4TEST/OUTBOUND/ORDERS/

Можно вовсе не использовать шаблоны, тогда все документы будут попадать в любую папку.

Например, шаблон:

/${addInfo.path}

Разработать реализацию FtpCustomAddInfoProvider, которая бы возвращала переменную path. Например, если она будет равна some/path/type/kind/outbound, то путь будет следующим:

/some/path/type/kind/outbound

Для шаблонизации пути используется компонент StringSubstitutor из библиотеки commons-text от Apache с небольшой модернизацией.

Подробнее можно ознакомиться в тестах к либе.

Отправить сообщение можно с помощью интерфейса EdiService, передав ему EdiProviderType.FTP. Доступные методы:

  • generateEdiXml - доступен, но пока что реализованных генераторов не имеет ввиду ненадобности. Можно расширять список генераторов в рамках бандла ecos-edi-ftps-lib или других, если появится такая необходимость.

  • sendEdiXml - отправка сообщения, данные которого сериализованы в EdiXmlRequest на FTP-сервер.

Сервис EdiService доступен из контекста Alfresco и микросервиса integrations-app.

4. Принципы работы при получении сообщений

Для получения сообщений мы проходим через 3 фазы:

  1. Ищем сообщения.

  2. Обрабатываем сообщения.

  3. Фиксируем, что сообщение обработано.

4.1. Обход в поиске сообщений

Для поиска документов - используется рекурсивный обход по папкам. Алгоритм не забирает все документы разом и отправляет их на обработку, а запоминает место последнего найденного документа, отправляет на обработку и позже возобновляет обход с той же точки. Реализовано это в виде итератора FtpWalkIterator.

Итератору скармливаются параметры Inbound documents folder path template (далее - шаблон поиска входящих) и Search documents in subdirectories (флаг поиска в поддиректориях), которые описаны в п.2.3.

Шаблон поиска входящих разбивается на уровни по папкам. То есть, например, шаблон /${addInfo.counterparty.esk}_S4TEST/INBOUND/${document.type} разобьется на 4 части:

/
/${addInfo.counterparty.esk}_S4TEST
/${addInfo.counterparty.esk}_S4TEST/INBOUND
/${addInfo.counterparty.esk}_S4TEST/INBOUND/${document.type}

После этого, части будут преобразованы в корректные регулярные выражения. То есть, эти части будут иметь теперь следующие значения:

/
/(?<addInfo.counterparty.esk>[\\w\\s-]+)_S4TEST
/(?<addInfo.counterparty.esk>[\\w\\s-]+)_S4TEST/INBOUND
/(?<addInfo.counterparty.esk>[\\w\\s-]+)_S4TEST/INBOUND/(?<document.type>ORDERS|ORDRSP|DESADV|RECADV)

Обратите внимание, замена происходит не просто на регулярки, а создаются группы для того чтоб потом вынуть эти значения для создания события Event (внутри на самом деле еще заменяются точки на A1B2C3 строки, но это опустим, чтобы не ухудшать читаемость). Так же, обратите внимание, document.type и document.lowerType преобразуются в конкретные значения enum, а остальные переменные - в регулярки из букв, цифр, пустых символов или символа “-”.

Если включен флаг поиска в поддиректориях - к последнему регулярному выражению добавляется “.*“. Таким образом становится возможным поиск по подпапкам.

Так же, есть возможность указывать не стандартную регулярку, а свою. Пример -

/${addInfo.counterparty.esk(\d+)}_S4TEST/INBOUND/${document.type}

Алгоритм обхода:

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

  1. Инициализируем итератор, загрузив в очередь файлы из папки “/” (из рута). Этот шаг выполняется только 1 раз.

  2. Берем из очереди следующий элемент.

  3. Определяем его уровень (по количеству символов “/“). Берем соответствующий этому уровню regexp (или последний, если уровень больше чем есть regexp’ов).

  4. Проверяем совпадение по regexp.

    3.1. Если совпадает - смотрим, папка это или файл. Если папка - выбираем из нее список файлов и ложим в начало очереди для дальнейшего разбора, переходим на пункт 1. Если файл (для файлов проверяем только на соответствие последнему регулярному выражению) - отправляем его на обработку.

    3.2. Не совпадает - выбрасываем элемент из очереди. Переходим на пункт 1.

4.2. Обработка сообщения

Этот шаг состоит из 2х пунктов:

  • Наполнения Event (Что такое Event в интеграции - можно почитать тут Описание работы интеграции. Как уже написано выше, необходимо запомнить группы из regexp. Сделано это для того, чтобы передать по тем же ключам значения в структуру Event. То есть, для шаблона поиска входящих /${addInfo.counterparty.esk}_S4TEST/OUTBOUND/${document.type} - в структуру Event пробросятся значения из пути сообщения на FTP-сервере.

  • Дальше, созданный Event отправляется в EdiStateService (Описание работы интеграции) для обработки дальше системой силами роутов Camel.

4.3. Фиксация обработанного сообщения

После успешной (или не успешной) обработки сообщения - необходимо зафиксировать, что сообщение было обработано. Происходит это за счет выбранной политики, переданной через конфигурацию Inbound processing policy (см. п.2.3).

4.3.1. Политика MOVE_AFTER_PROCESSING

В случае успеха - перемещаем файл в папку, которая указана в конфигурации Inbound documents success folder path template (см. п.2.3).

В случае провала - перемещаем файл в папку, которая указана в конфигурации Inbound documents error folder path template (см. п.2.3).

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

4.3.2. Политика DELETE_ON_SUCCESS

В случае успешно обработанного события - файл удаляется с FTP-сервера.

В случае провала - ничего не происходит.