Статья о том, как перекладывать файлы. По мотивам вебинара "SOA Pattern: File Gateway". Задача состоит в том, чтобы переложить пустой файл из одной директории в другую при помощи WSO2 ESB.
Для перемещения файлов нужно использовать VFS-транспорт. По умолчанию он заблокирован и не отображается в списке доступных протоколов передачи при создании прокси-сервисов.
Открываем файл
<ESB_HOME>/repository/conf/axis2/axis2.xml
и раскомментируем две строчки. Первую - в разделе входящих соединений "Transport Ins (Listeners)":
<transportReceiver name="vfs" class="org.apache.synapse.transport.vfs.VFSTransportListener"/>
Вторую - в разделе исходящих соединений "Transport Outs (Senders)":
<transportSender name="local" class="org.wso2.carbon.core.transports.local.CarbonLocalTransportSender"/>
Теперь при создании нового прокси-сервиса появляется опция vfs.
Будем добавлять параметры, чтобы настроить передачу файлов. Задаём интервал опроса файловой системы:
transport.PollInterval = 2000ms
Подобным образом добавляем следующие параметры.
Папка источник:
transport.vfs.FileURI = file://D:/q/in
Шаблон названия файла:
transport.vfs.FileNamePattern = .*\.txt
Тип содержимого файлов:
transport.vfs.ContentType = text/plain
Действие после обработки файла:
transport.vfs.ActionAfterProcess = MOVE
transport.vfs.MoveAfterProcess = file://D:/q/processed
Действие в случае ошибки при обработки файла:
transport.vfs.ActionAfterFailure = MOVE
transport.vfs.MoveAfterFailure = file://D:/q/failure
Если перемещать обработанные файлы не нужно, пишем DELETE вместо COPY и надобность в указании папок для перемещаемых файлов в этом случае отпадает (см. здесь)
Переходим к созданию последовательностей медиаторов.
Ограничимся созданием встроенной входящеё последовательности.
Определим сначала свойства медиатора Send, который зададим позже. Важно, чтобы свойства предшествовали мадиатору, т.к. мы находимся внутри последовательности. Если свойства будут определены после медиатора, в котором они используются, их значения будут недоступны.
Свойство
Добавим ещё один медиатор Property и запишем в него имя обрабатываемого файла.
Извлекаем имя фала с помощью выражения:
get-property('transport', 'FILE_NAME')
Создадим третий медиатор Property.
Передаём определяем имя конечного файла, который запишет VFS. Если не указать параметр transport.vfs.ReplyFileName, то будет создан файл с именем по умолчанию - response.xml.
Выполняемый трюк с перебросом имени файла описан в нескольких источниках:
http://stackoverflow.com/questions/10492050/wso2-how-to-set-replyfilename-in-vfs
Создадим теперь медиатор Send, который запишет обрабатываемый файл в новое место.
Конечная точка (Endpoint) будет у нас встроенной, чтобы сократить число шагов.
Выбираем адресную конечную точку (Address Endpoint).
В качестве адреса передаём путь к директории, в которую будем складывать файлы:
vfs:file://D:\q\out
Префиксы vfs: и file: означают, что мы будем работать с файловой системой через VFS.
Запоминаем настройки медиатора Send, содержащего созданную только что конечную точку.
Сохраняем последовательность.
Завершаем определение прокси-сервиса.
В итоге получилась такая конфигурация:
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="fileproxy"
transports="vfs"
statistics="disable"
trace="disable"
startOnLoad="true">
<target>
<inSequence>
<property name="OUT_ONLY" value="true" scope="default" type="STRING"/>
<property name="filename"
expression="get-property('transport', 'FILE_NAME')"
scope="default"
type="STRING"/>
<property name="transport.vfs.ReplyFileName"
expression="get-property('filename')"
scope="transport"
type="STRING"/>
<send>
<endpoint>
<address uri="vfs:file://D:\q\out"/>
</endpoint>
</send>
</inSequence>
</target>
<parameter name="transport.vfs.ActionAfterProcess">MOVE</parameter>
<parameter name="transport.PollInterval">2000ms</parameter>
<parameter name="transport.vfs.MoveAfterProcess">file://D:/q/processed</parameter>
<parameter name="transport.vfs.FileURI">file://D:/q/in</parameter>
<parameter name="transport.vfs.MoveAfterFailure">file://D:/q/failure</parameter>
<parameter name="transport.vfs.FileNamePattern">.*\.txt</parameter>
<parameter name="transport.vfs.ContentType">text/plain</parameter>
<parameter name="transport.vfs.ActionAfterFailure">MOVE</parameter>
<description/>
</proxy>
Ограничимся созданием встроенной входящеё последовательности.
Определим сначала свойства медиатора Send, который зададим позже. Важно, чтобы свойства предшествовали мадиатору, т.к. мы находимся внутри последовательности. Если свойства будут определены после медиатора, в котором они используются, их значения будут недоступны.
Свойство
OUT_ONLY
= true говорит шине о том, что не нужно ждать ответа от сервиса, которому отправлено сообщение. Добавим ещё один медиатор Property и запишем в него имя обрабатываемого файла.
Извлекаем имя фала с помощью выражения:
get-property('transport', 'FILE_NAME')
Создадим третий медиатор Property.
Передаём определяем имя конечного файла, который запишет VFS. Если не указать параметр transport.vfs.ReplyFileName, то будет создан файл с именем по умолчанию - response.xml.
Выполняемый трюк с перебросом имени файла описан в нескольких источниках:
http://stackoverflow.com/questions/10492050/wso2-how-to-set-replyfilename-in-vfs
Создадим теперь медиатор Send, который запишет обрабатываемый файл в новое место.
Конечная точка (Endpoint) будет у нас встроенной, чтобы сократить число шагов.
Выбираем адресную конечную точку (Address Endpoint).
В качестве адреса передаём путь к директории, в которую будем складывать файлы:
vfs:file://D:\q\out
Префиксы vfs: и file: означают, что мы будем работать с файловой системой через VFS.
Запоминаем настройки медиатора Send, содержащего созданную только что конечную точку.
Сохраняем последовательность.
Завершаем определение прокси-сервиса.
В итоге получилась такая конфигурация:
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="fileproxy"
transports="vfs"
statistics="disable"
trace="disable"
startOnLoad="true">
<target>
<inSequence>
<property name="OUT_ONLY" value="true" scope="default" type="STRING"/>
<property name="filename"
expression="get-property('transport', 'FILE_NAME')"
scope="default"
type="STRING"/>
<property name="transport.vfs.ReplyFileName"
expression="get-property('filename')"
scope="transport"
type="STRING"/>
<send>
<endpoint>
<address uri="vfs:file://D:\q\out"/>
</endpoint>
</send>
</inSequence>
</target>
<parameter name="transport.vfs.ActionAfterProcess">MOVE</parameter>
<parameter name="transport.PollInterval">2000ms</parameter>
<parameter name="transport.vfs.MoveAfterProcess">file://D:/q/processed</parameter>
<parameter name="transport.vfs.FileURI">file://D:/q/in</parameter>
<parameter name="transport.vfs.MoveAfterFailure">file://D:/q/failure</parameter>
<parameter name="transport.vfs.FileNamePattern">.*\.txt</parameter>
<parameter name="transport.vfs.ContentType">text/plain</parameter>
<parameter name="transport.vfs.ActionAfterFailure">MOVE</parameter>
<description/>
</proxy>
Ссылки на документацию:
https://docs.wso2.com/display/ESB481/VFS+Transport
https://docs.wso2.com/display/ESB481/Configuring+Transports