Шаблоны (templates) в JBoss Drools
Термины и определения
DRL — сокращение от Drools Rules Language, формат написания drools правил.
KIE — общедоступное API, разрабатываемое компанией JBoss, в него входят несколько технологий, в т.ч. Drools.
MVEL — гибридный динамически/статически типизированный, внедряемый язык выражений в среду выполнения для платформы Java.
Введение
Шаблоны правил(templates) в Drools — способ генерации правил «на лету» с использованием шаблона файлов и табличных источников данных. Под табличными источниками данных мы имеем в виду данные, которые могут быть представлены в таблице. Типичными примерами такого рода источников данных являются электронные таблицы и таблицы в базах данных.
Одной из наиболее распространенных проблем при работе с Drools является генерация правил, если они имеют эквивалентную структуру, но разные значения в блоках when и/или then. Одним из способов решения этого сценария является использование шаблонов(templates).
Шаблоны обладают рядом преимуществ по сравнению с обычными правилами:
- позволяют хранить данные, используемые в правиле, в базе данных (или другом формате);
- генерировать правила, основанные на значениях в источниках данных;
- использовать данные для любой части правила (например, имя свойства, имя шаблона и т. д.);
- запускать разные шаблоны используя одинаковые данные.
Еще одно большое преимущество шаблонов правил заключается в том, что данные и структура правил полностью отделены друг от друга. Тот же шаблон может использоваться для разных данных, и один и тот же набор данных может использоваться для разных шаблонов. Это обеспечивает гибкость в сравнении с обычными правилами.
Структура шаблона
power-for-gpu.drl
Строка 1: все шаблоны начинаются с заголовка — “template header”
Строки 2-4: список переменных шаблона в порядке появления их из источника.
Строка 5: пустая строка определяющая конец объявления полей из шаблона.
Строка 6-9: стандартные для drools объявления.
Строка 10: ключевое слово “template” сигнализирующее о начале шаблона правила. В файле шаблона может быть несколько шаблонов. Шаблон должен иметь уникальное имя.
Строка 12-19: тело шаблона. Шаблоны правил построены на MVEL для подстановки переменных внутри правила используется синтаксис @{token_name}, где token_name — имя переменной шаблона. В указанном примере используется выражение @{row.rowNumber}, при помощи которого мы можем получить номер строки данных, что позволяет сгенерировать уникальное имя правила.
Строка 20: “end template” сигнализирует о конце шаблона правила.
Для каждой строки данных будет сгенерировано правило со значениями данных, замененных для токенов в шаблоне.
Одно из преимущество шаблонов над еще одним похожим механизмом параметризации в Drools — decision table, состоит в том, что переменные в шаблоне правила могут использоваться в любом месте правила: имя шаблона, имя свойства и т.д. Также переменные могут использоваться в любом порядке и использоваться несколько раз, если это необходимо.
Создание набора данных для шаблона
Для создания наборов данных, используемых в шаблонах, в библиотеке Drools определены классы drools-templates. Эти классы необходимы для анализа шаблона и создания DRL из набора данных. В качестве источника для набора данных поддерживаются: массивы, объекты, электронные таблицы и наборы результатов SQL.
Работа с шаблонами правил
Для шаблонов, используемых на основе электронных таблиц, Drools поддерживает их определение в файле kmodule.xml, используя специальный элемент конфигурации на базе KIE Base:
Приведенный фрагмент кода показывает, как шаблон power-for-gpu.drt с источником данных из электронной таблицы с именем template-data.xls включается в template-KBase KIE Base.
Далее будет использоваться программный подход для заполнения шаблонов. В последующих примерах происходит заполнение шаблона DRL, а затем на его основе создается KIE-сессия.
В приведенных далее примерах будет использоваться вспомогательный метод для создания KIE сессии на основе DRL строки:
Указанный метод на основе DRL строки в качестве параметра, при помощи класса KieHelper компилирует и создает базу KIE. Этот метод также проверяет наличие ошибок или предупреждений во время DRL компиляции. Как только база KIE будет построена, метод возвращает новую KIE-сессию.
Источник данных — электронные таблицы
Довольно популярным и удобным решением, является применение электронных таблиц, в качестве источника данных для шаблона, т.к. для заполнения человеку не нужно обладать глубокими техническими навыками и изменять код, а работа происходит напрямую в электронной таблице.
В приведенной таблице используются лишь необходимые данные для шаблона и полезные заголовки для человека, которому необходимо редактировать таблицу. Таблица не содержит никакой информации о шаблоне, который должен использоваться и структуре правил, которые необходимо создать.
Чтобы преобразовать это в таблицу DRL, используем файл шаблона, созданный ранее (power-for-gpu.drl) и вспомогательный метод createKieSessionFromDRL.
Первые две строки кода получают шаблон и файл источника данных, как объекты InputStream. В четвертой строке используется объект класса-помощника ExternalSpreadsheetCompiler для преобразования файла шаблона и данных в таблицу DRL. Метод compile из ExternalSpreadsheetCompile принимает четыре аргумента: источник данных, шаблон, строка и столбец внутри таблицы, где начинаются данные.
Источник данных — массив
Еще одним способом предоставления данных шаблону является двумерный строчный массив. В этом случае, первое измерение массива используется как строка, а второе измерение как столбец.
В вышеприведенном коде показано, как экземпляр класса DataProviderCompiler может использоваться для обработки шаблона с использованием двумерного массива строк в качестве источника данных. Данные инкапсулируются внутри экземпляра arrayDataProvider. Класс ArrayDataProvider реализует интерфейс DataProvider. Если необходимо создать специальный, настраиваемый источник информации, который необходимо загрузить в шаблон правила, необходимо реализовать собственный DataProvider и связать его с шаблоном с помощью DataProviderCompiler.
Источник данных — объекты
Более объективно-ориентированный подход к предоставлению данных в шаблон – это использование объектов как модель. Вместо двумерного массива строк используются наборы объектов для хранения данных, требуемых нашими шаблонами.
В качестве примера, создадим класс хранения данных для нашего сценария:
Когда объекты используются как источник данных шаблона, имена переменных, объявленных в заголовке шаблоне, должны соответствовать именам полей в классе модели.
Указанный выше код показывает как коллекция объектов PowerForGPUModel используется в качестве источника данных для шаблона.
Источник данных — набор результатов SQL
Последний вариант источника данных для шаблонов — наборы результатов SQL. Под набором результатов SQL подразумевается класс java.sql.ResultSet. Экземпляр этого класса можно получить разными способами, например, используя JDBC.
Предположим, у нас есть таблица с именем GPU в базе данных:
Если мы хотим использовать информацию из этой таблицы для создания DRL с использованием шаблона правила, мы можем использовать следующий код:
В указанном примере используются стандартные классы JDBC: Connection, Statement и ResultSet. Сперва выполняется запрос к таблице GPU и получает его результат как ResultSet. Затем, используя класс из библиотеки Drools – ResultSetGenerator, преобразуем ResultSet и шаблон в DRL.
Заключение
Шаблоны правил являются полезным механизмом, позволяющим генерировать правила, имеющие аналогичную структуру, но разные значения в блоках when и/или then. При помощи шаблонов в Drools решается проблема параметризации. Также библиотека Drools позволяет использовать в качестве источников данных для шаблона разные структуры, что облегчает труд разработчиков.
DevOps. Continuous Integration на примере Jenkins Завершён проект «Система управления игровыми компьютерными клубами»