MongoDB Connector для Mule 4 (Anypoint Studio) — об этом не пишут в документации

Всем привет. Я Василий — Technical Leader s SoftServe. Мой коллега Ivan Tukin ранее писал Обзор iPaaS платформы MuleSoft Anypoint. Одна из платформ, которую используем для собственных нужд и нужд заказчиков для интеграции учетных систем и сторонних сервисов. В этой статье хочу описать свой опыт в конкретном кейсе, когда использовал MuleSoft 4 в связке и MongoDB. Для реализации этой связки необходимо использовать MongoDB Connector — Mule 4. Во время реализации проекта столкнулся с рядом неявных мест, которые слабо описаны в документации и пришлось потратить множество времени и даже прибегнуть к reverse engineering, чтобы достичь нужный результат. Данная статья поможет Вам сэкономить время и научиться «справляться» с подобной связкой: MuleSoft 4 — MongoDB Connector — MongoDB.

В Anypoint Studio (десктопное приложение для создания проекта) есть Mule Palette, на которой расположены как стандартные так и загружаемые модули.

При подключении к базе данных как правило выбирается раздел Database слева и вид команды справа (например Select). Выбор же базы данных настраивается в конфигураторе — выбирается вид базы данных и необходимый JDBC Driver:

С этого момента и начинается путаница. Дело в том, что под модулем Database подразумевается SQL Database, MongoDB Connector подключается иначе. Для этого на Mule Palette нужно выбрать Search in Exchange...

В появившемся окне нужно аутентифицироваться использую MuleSoft креды и в поле поиска набрать MongoDB, после чего загрузить внешний модуль. В результате этих манипуляций на Mule Palette появится нужный нам модуль.

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

При настройки конфигурации обязательно заполнить поля логина и пароля для подключения к базе. Если же у вас нет пользователя для нужной базы данных, тогда необходимо его создать. Инструкцию по созданию пользователя в MongoDB можете прочитать тут.

Если же логин/пароль не указан, то при тестировании связи появляется ну уж совсем не явная ошибка.

Когда же верно указаны креды, то получаем позитивный результат.

Итак, модуль мы загрузили, связь с базой мы настроили, теперь начинаем использовать инструменты, которые предоставляет этот модуль. Инструменты действительно разнообразные и довольно удобные (Count Documents, Find Documents, MapReduce и так далее). Список инструментов модуля тут.

В моем же случае нужно использовать такую MongoDB команду как aggregate, которого нет в нашем модуле. Список команд тут. История получения нужного результата достойна отдельной статьи, но здесь опишу результаты, которые вряд ли можно найти на просторах интернета. Подобных вопросов как использование аггрегации при помощи MongoDB Connector я нашел два, в одном ответа не было уже пол года, в другом ответ включал в себя команду eval, которая уже отсутствует в последних версиях MongoDB.

Если же Вам нужно использовать команды, которых нет среди модуля, тогда нужно выбирать один из двух вариантов: Execute command, Execute Generic Command.

В официальной документации не указаны примеры для корректной настройки этих команд, чтобы получить нужный результат. Пришлось прибегнуть к reverse engineering и методом экспериментов добиться результата.

Execute Command использует два поля: Command Name, Command Value.

Эти значения используются в качестве первой пары ключ-значение в объекте MongoDB команды, список которых указывал выше. Вот пример для команды find.

Так вот первая пара ключ-значение, а именно «find»: и есть те поля, которые заполняем в Command Name и Command Value.

Что же касается aggregate, то эта команда имеет несколько пар ключ-значение, которые обязательны для исполнения команды (aggregate, pipeline, cursor).

Для подобного нам нужно использовать Execute Generic Command.

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

Есть единственное поле Command, которые и нужно заполнить.

Вот полный текст кода в данном поле

output application/json
---
{
  "aggregate": "ordered_grouped_donors",
  "pipeline": [{"\$skip": 100000 * (vars.counter as Number - 1)}, {"\$limit": 100000}, {"\$group": {"_id": false, "users": {"\$push": {"_id": "\$_id", "value": "\$value"}}}}, {"\$unwind": {"path": "\$users", "includeArrayIndex": "rank"}}, {"\$unset": "_id"}, {"\$set": {"donor_title": "\$users._id.donor_title", "value": "\$users.value"}}, {"\$unset": "users"}, {"\$merge": {"into": "donor_rank"}}],
  "allowDiskUse": true,
  "cursor": {},
}

Код в XML формате:

<mongo:execute-generic-command doc:name="aggregate" doc:id="5957a61b-efbd-4e30-9a9d-27c4c0f66450" config-ref="MongoDB_Config">
			<mongo:command><![CDATA[#[output application/json
---
{
  "aggregate": "ordered_grouped_donors",
  "pipeline": [{"\$skip": 100000 * (vars.counter as Number - 1)}, {"\$limit": 100000}, {"\$group": {"_id": false, "users": {"\$push": {"_id": "\$_id", "value": "\$value"}}}}, {"\$unwind": {"path": "\$users", "includeArrayIndex": "rank"}}, {"\$unset": "_id"}, {"\$set": {"donor_title": "\$users._id.donor_title", "value": "\$users.value"}}, {"\$unset": "users"}, {"\$merge": {"into": "donor_rank"}}],
  "allowDiskUse": true,
  "cursor": {},
}]]]></mongo:command>
		</mongo:execute-generic-command>

И сейчас нужно быть внимательным: команда должна иметь формат данных Binary, для этого я использую первые 2 строки:
output application/json
---

Также если нужно использовать динамические значения в команде (например из переменных MuleSoft, то знак «$» нужно эскейпить при помощи «\», т.к. в данном режиме MuleSoft воспринимает ’$’ как зарезервированный символ). Если же динамических данный нет и Вы вводите строку, тогда ’\’ нужно будет удалить. Динамический и статический режимы переключаются при помощи кнопки ниже.

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

LinkedIn
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Подписаться на комментарии