Статьи

Реализация пользовательской проверки данных JSON или карт с помощью Mule DevKit


Проверка данных может быть легкой с помощью Mule, если ваши сообщения имеют определенные форматы.
Например, полезные данные XML можно проверить на корректность с помощью
схемы XML или фильтров XPath.  Фильтры типа полезной нагрузки и оценка выражений OGNL могут иметь большое значение для подтверждения правильности ваших полезных нагрузок POJO.

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

Создание модуля для пользовательской проверки

Как было показано ранее, Mule DevKit — это отличный способ добавить первоклассную поддержку со схемой конфигурации для пользовательских процессоров сообщений. Давайте реализуем обработчик сообщений для Acme Software, Inc, который принимает массив JSON на конечной точке HTTP и отфильтровывает из него недопустимые продукты.

Мы начнем с создания модуля для проверочных расширений нашей вымышленной компании, используя devkit mvn archetype:

mvn archetype:generate -DarchetypeGroupId=org.mule.tools.devkit - DarchetypeArtifactId=mule-devkit-archetype-generic -DarchetypeVersion=3.0.1 - DarchetypeRepository=http://repository.mulesoft.org/releases/ -DgroupId=acmesoft.com -DartifactId=validator-module -Dversion=1.0-SNAPSHOT -DmuleVersion=3.2.0 - DmuleModuleName=Validator -DmuleModulePackage=com.acmesoft.integration

Это дает нам проект Maven, который мы можем использовать для размещения пользовательских валидаторов нашей компании. Эти валидаторы будут «первоклассными» гражданами в конфигурационном файле Mule, счастливо живя рядом со встроенными обработчиками сообщений Mule.

Реализация пользовательского валидатора

Команда mvn, которую мы выполнили выше, создаст класс ValidatorModule в пакете com.acmesoft.integration. Здесь мы реализуем код для нашего собственного процессора. Мы изменим реализацию заглушки, чтобы она выглядела следующим образом:

@Module(name = "validator", schemaVersion = "1.0-SNAPSHOT")
public class ValidatorModule {


    /**
     * Processor to filter our invalid products from a List payload.
     * <p/>
     * {@sample.xml ../../../doc/Validator-connector.xml.sample validator:my-processor}
     *
     * @param products The products to validate
     * @return The products which are valid
     */
    @Processor(name = "product")
    public Object validateProducts(@Payload List<Map> products) throws Exception {

        List<Map> validProducts = new ArrayList<Map>();

        for (Map product : products) {
            if (product.containsKey("sku") || product.containsKey("product_id")) {
                validProducts.add(product);
            }
        }

        return validProducts;
    }


}

Атрибут «name» в аннотации @Module класса указывает пространство имен модуля. Аналогичным образом, атрибут «name» в аннотации @Processor определяет имя элемента XML в конфигурации. Конфигурация XML для нашего обработчика сообщений будет выглядеть следующим образом:

<validator:product/>

Давайте посмотрим на реализацию validateProducts. Указание аннотации @Payload для одного из аргументов позволяет нам определить полезную нагрузку. В этом случае мы ожидаем List of Maps, который является допустимым типом возврата json-to-object-transformer Муле.

Затем мы перебираем каждое представление Map продукта и отфильтровываем те, которые не содержат ключей «sku» или «product_id». Наконец, мы возвращаем отфильтрованный список, который будет распространяться на следующий процессор в цепочке.

Настройка пользовательского валидатора

Теперь мы готовы поместить валидатор в поток. Мы примем данные продукта JSON на входящей конечной точке HTTP, отфильтруем недопустимые продукты и передадим отфильтрованные результаты на исходящей конечной точке виртуальной машины:

 <flow name="Product Submission">
    <http:inbound-endpoint address="http://localhost:8080/products"/>
    <byte-array-to-string-transformer/>
    <json:json-to-object-transformer returnClass="java.util.ArrayList"/>
    <validator:product/>
    <vm:outbound-endpoint path="products.out"/>
</flow>

Полезная нагрузка сначала преобразуется из байтового массива в строку. Преобразователь json-to-object перемещает закодированные данные JSON в формат списка карт. Это легче использовать, чем необработанный JSON для нашего варианта использования. Затем в игру вступает наш валидатор продукта, отфильтровывая недействительные сообщения перед окончательной отправкой результатов в очередь виртуальных машин «products.out».

Использование DevKit с модулем Mule имеет преимущества по сравнению с «одноразовой» реализацией с элементом пользовательского процессора. Используя модуль, мы теперь можем делиться валидаторами между несколькими проектами Mule. Глубокая интеграция со схемой Mule позволяет завершать код и документировать в большинстве IDE, снижая барьер входа для других, чтобы использовать пользовательские функции. Наконец, уровень усилий для достижения вышеизложенного тривиализируется с использованием аннотаций DevKit.