четверг, 25 сентября 2014 г.

jboss drools bpm

Построение сервисов с Drools Rule Engine, ONJava.com

Давно хотел разобраться с системами управления бизнес-правилами (Business Rules Management Systems - BRMS). Вопросом не владею и вообще попал на тему после материала Intalio|BPMS 5.0/OpenLexicon Tutorial. Но после некоторого рассмотрения понял, что это очень похоже на продукционный тип экспертных систем. Времени на тему как всегда не хватало, но некоторое время назад встретил статью на IBM DeveloperWorks, а вчера прочитал еще одну относительно свежую статью по теме, которую приведу ниже.

ЗЫ

В процессе поставил открытый словарь StarDict, и вот уже думаю забросить Lingvo. Если кому нужен качественный функциональный словарь - посмотрите обязательно. Единственный непривычный момент это интерфейс, при этом общая функциональность на высоте. Это и множество доступных словарей, возможности использования интернет-словарей и сервисов, и ....

Building Enterprise Services with Drools Rule Engine
by Birali Hakizumwami
01/17/2007
Используя машину правил бизнес-логику приложения можно вынести для совместного использования. Такой подход расширяет возможности бизнес-пользователей и экспертов предметной области бизнеса, упрощая изменение и управление правилами. Поскольку правила могут часто изменяться, кодирование таких правил непосредственно в приложении усложняет дальнейшее обслуживание приложения. Статья в деталях показывает как построить архитектуру сервиса с использованием Drools в бизнес-решении. Этот сервис может быть частью общей SOA инфраструктуры предприятия. Он может быть отдельным сервисом, который используют подписанные потребители по модели, или частью составного сервиса, предоставляющего комплексную функциональность. Для того чтобы проиллюстрировать этих моменты, статья показывает, как благодаря использованию машины правил Drools, сервис может спрятать сложность автоматизации решений ипотечного андеррайтинга которые ежедневно принимаются ипотечной компанией.
Машина правил, такая как Drools предлагает соответствующие алгоритмы, которые могут определять какие правила и в каком порядке нужно запустить, а также предоставляет средства для разрешения конфликтов. Она поддерживает просмотр фактов и анализ правил которые могут запускаться на их основе, в результате вывод (консеквент consequence) одного из правил влияет на начальный факт, или запускает / останавливает другие правила по необходимости. За счет использования машины правил, быстро изменяющиеся бизнес-политики и правила можно выделить таким образом, чтобы они хранились и обслуживались самостоятельно в одном месте. Остальные приложения предприятия могут иметь доступ к этой функциональности через слой служб с четко определенными контрактами. Поведение службы можно изменять без изменения интерфейса контракта или необходимости повторной компиляции и развертывания. Правила хранятся в файле в удобной для человека форме, так что их можно изменить при помощи текстового редактора или редактора правил. Многие ведущие аналитики отрасли пришли к заключению, что для приложений, занимающихся интенсивным принятием решений, значительно более продуктивным решением является комплексное построение и изменение правил через системы основанные на правилах, чем специализированный код.

Машина Правил Drools

Drools это JSR-94-совместимая машина правил, которая использует Rete алгоритм, разработанный Чарльзом Форги. Простыми словами, Rete строит дерево всех правил в форме машины состояний. Он начинает с фактов, входов на верхнем уровне узлов дерева, как параметров правил, и работает вниз по дереву, когда они соответствуют условиям и пока они не достигают листьев узлов (консеквентам правил).
В этой статьи в качестве инструмента для написания и тестирования правил мы используем JBoss Rules Workbench IDE. JBoss Rules workbench поставляется как подключаемый модуль Eclipse, который позволяет вам создавать и управлять правилами в рамках Eclipse. Это дополнительный инструмент; и при условии, что подключены соответствующие библиотеки Drools, для написания и развертывания правил можно использовать любой другой инструмент. Подробные инструкции о том, как получить и установить этот подключаемый модуль можно найти в Drools documentation site.
Ниже приводится краткое описание основных библиотек, составляющих машину правил Drools:
  • drools-core.jar: Содержит ядро машины, компоненты времени исполнения реализующие RETE и LEAPS алгоритмы. Это единственная зависимость времени исполнения, которая необходима для предварительно откомпилированных и развернутых правил в виде Пакета или объектов RuleBase.
  • drools-compiler.jar: Содержит компилятор / построитель компонент, который принимает исходные файлы правил и строит исполняемые базы правил. Как мы уже упоминали, для откомпилированных правил этот .jar файл не нужен. Этот .jar зависит от drools-core.
  • drools-jsr94.jar: Содержит JSR-94-совместимую реализацию.
  • drools-decisiontables.jar: Содержит таблицу решений компилятора компонент. Он зависит от компонента drools-compiler. Поддерживает входные форматы Excel CSV.
Есть и другие зависимости, которые нужны приведенным выше компонентам; для полного перечня смотрите Drools documentation.

Служба ипотечного андеррайтинга использующая Drools

Следующий раздел демонстрирует подробности того, как машина правил Drools может быть использована для в архитектуре службы автоматизации ипотечного андеррайтинга, в качестве части общего SOA решения предприятия. При том, что мы говорим в примере об ипотечном андеррайтинге, это обсуждение можно применить к любому другому сектору бизнеса, помимо финансовых услуг (здравоохранение, телекоммуникации, и т.д.) где необходимо выделить подмножество бизнес-правил в качестве сервиса предприятия.
Пример был упрощен для ясности, и особое внимание было уделено возможностям машины правил Drools. Рисунок 1 показывает просто пример архитектуры машины андеррайтинга.
Архитектура машины андеррайтинга
Рисунок 1. Архитектура машины андеррайтинга
Архитектура описывается тремя компонентами:
  • Система заявок на получение кредита: Охватывает и хранит все данные отправленные в кредитное приложение. Она выступает в качестве потребителя сервиса андеррайтинга: посылает запросы андеррайтинга и обрабатывает принятые решения.
  • Сервис андеррайтинга: Разработан как вызываемый сервис, который может быть как веб-службой таки и некоторым API. Этот компонент вызывает API машины правил Drools и, выполняя оценку правил андеррайтинга, производит ответное сообщение, сообщая в нем статус андеррайтинга. Служба также позволяет простую модификацию правил.
  • Службы поддержки: Эти службы необходимы для заполнения некоторой информации в кредитном приложении, информации заемщика, и свойственной ему информации: услуга кредитного скоринга, услуга оценки имущества, и модель доступности услуги.



Мы начнем с написания основного теста JUnit, которой содержит два тестовых метода: testSuccessfulApplication() имитирует успешную подачу заявки о кредите, и testAllFeedbackMessages()имитирует неудачную заявку и отображение полного ответного сообщения.
public class TestUnderwritingService extends TestCase {

   public void testSuccessfulApplication() throws Exception{
       Borrower bo = new Borrower();
       bo.setAge(40);
       bo.setGrossIncome(290000.0);

       // Call the CreditScore Service to fill the credit score
       CreditScoringService css = new CreditScoringService();
       css.setScore(700); // Value hard-coded for testing purpose
       css.getScore(bo);

       // Call the affordability model service
       AffordabilityModelService ams = new AffordabilityModelService();
       ams.runModel(bo);

       Property po = new Property();
       po.setPurpose(Flag.OWNER_OCCUPIED);
       po.setYearBuilt(2003);
       po.setZipCode("22102");

       // Call the PropertyValue service
       PropertyValuationService pvs = new PropertyValuationService();
       pvs.setPropertyValue(800000.0); // hard-coded for testing
       pvs.getPropertyValue(po);

       // Create a Loan Application
       LoanApplication la = new LoanApplication();
       la.setBorrower(bo);
       la.setProperty(po);
       la.setLoanAmount(390000.0);
       la.setLoanToValueRatio(la.getLoanAmount()/po.getValue()*100);

       // Calls the underwriting service
       UnderwritingService ue = new UnderwritingService();
       ue.evaluate(la);

       System.out.println("\nTesting successful application");
       System.out.println("=============================");
       System.out.println(la);
       System.out.println("Feedback message size=" +
                               la.getFeedbackMsgSize());
       System.out.println("Affordability Flag=" +
                               la.getAffordabilityFlag());
       System.out.println("Underwriting Decision=" +
                               la.getStatus());

       //assertEquals(la.getStatus(), LoanApplication.PASSED);
       assertEquals(la.getStatus(), Flag.PASSED);

   }

   public void testAllFeedbackMessages() throws Exception{
       Borrower bo = new Borrower();
       bo.setAge(17);
       bo.setGrossIncome(170000.0);

       // Call the CreditScore Service to fill the credit score
       CreditScoringService css = new CreditScoringService();
       css.setScore(500);
       css.getScore(bo);

       // Call the affordability model service
       AffordabilityModelService ams = new AffordabilityModelService();
       ams.runModel(bo);

       Property po = new Property();
       po.setPurpose(Flag.INVESTMENT);
       po.setYearBuilt(1961);
       po.setZipCode("22102");

       // Call the PropertyValue service
       PropertyValuationService pvs = new PropertyValuationService();
       pvs.setPropertyValue(800000.0);
       pvs.getPropertyValue(po);

       // Create a Loan Application
       LoanApplication la = new LoanApplication();
       la.setBorrower(bo);
       la.setProperty(po);
       la.setLoanAmount(700000.0);
       la.setLoanToValueRatio(la.getLoanAmount()/po.getValue()*100);

       //    Calls the underwriting service
       UnderwritingService ue = new UnderwritingService();
       ue.evaluate(la);

       System.out.println("\nTesting all feedback messages");
       System.out.println("=============================");
       System.out.println(la);
       System.out.println("Feedback message size=" + la.getFeedbackMsgSize());
       System.out.println("Affordability Flag=" + la.getAffordabilityFlag());
       System.out.println("Underwriting Decision=" + la.getStatus());

       assertEquals(la.getStatus(), Flag.FAILED);

   }
}



Тестовый сценарий инстанцирует бизнес-объекты Borrower,Свойства, и LoanApplication.
public class LoanApplication {

   private double loanAmount;
   private int creditScore;
   private double loanToValueRatio;
   private Flag affordabilityFlag=Flag.AFFORDABLE;
   private int feedbackMsgSize;

   private Borrower borrower;
   private Property prop;

   private Flag status=Flag.PASSED;

   private ArrayList feedbackMessages =
       new ArrayList();

 .../...  // getters and setters
}

public class Borrower {
   int age;
   double setAffordableLoanAmount;
   double grossIncome;
   int creditScore;
   .../...
}

public class Property {
   private Flag type;
   private Flag purpose;
   private String zipCode;
   private int yearBuilt;
   private double value;

   .../...
}
Следующее перечисления содержит все флаги используемые в этой статье:
public enum Flag {
   AFFORDABLE, NOT_AFFORDABLE, PASSED, FAILED, INVESTMENT, OWNER_OCCUPIED;
}
Как я упоминал ранее, сервисы поддержкиCreditScoringService,AffordabilityModelService, и PropertyValuationService сделаны частью приложения, но для этой статьи они выполнены как заглушки и возвращают жестко закодированные значения.
Другой класс, который используется в нашем тесте JUnit,UnderwritingService, содержит вызов API машины правил Drools.
public class UnderwritingService {
   public void evaluate(LoanApplication la)
       throws Exception{

       doRun("/Underwriting.drl", la);
       doRun("/Decision.drl", la);

   }

   private void doRun(String ruleFileName, LoanApplication la)
       throws Exception {

       RuleBase ruleBase = readRule(ruleFileName);
       WorkingMemory wm = ruleBase.newWorkingMemory();
       wm.assertObject(la);
       wm.assertObject(la.getBorrower());
       wm.assertObject(la.getProperty());
       wm.fireAllRules();

   }

   private RuleBase readRule(String ruleFileName)
       throws Exception {

       Reader source = new InputStreamReader(
               UnderwritingService.class.
                   getResourceAsStream(ruleFileName) );

       PackageBuilder builder = new PackageBuilder();
       builder.addPackageFromDrl( source );
       Package pkg = builder.getPackage();

       RuleBase ruleBase = RuleBaseFactory.newRuleBase();
       ruleBase.addPackage( pkg );
       return ruleBase;
   }

}



Остановимся на некоторых важных методах этого класса:
  • readRule: Загружает все правила, хранящиеся в файлеruleFileName и возвращает объекты RuleBase которые содержатся в пакете правил.
  • doRun: Создает новый экземпляр WorkingMemory, использующий assertObject для помещения известных фактов (LoanApplicationBorrower, and Property objects) в память, и вызывающий fireAllRules() на классеWorkingMemory. Мы используем объект RuleBase возвращаемый методом readRules() для создания нового WorkingMemory для каждой сессии, а затем удаляем его в конце.

Правила андеррайтинга с использованием файла Drools .drl

Мы начнем с описания процесса андеррайтинга и политик и тем как определить правила из этих политик. Представлены два .drl файла: Underwriting.drl содержит политики правил андеррайтинга, и Decision.drl содержащий правила принятия решений андеррайтинга. Процесс андеррайтинга обычно имеет две стадии:
  • Оценка возможности возврата заявителем:
    • Два соображения по оценке сможет ли заявитель возвратить ссуду.
    • Правила политики связанные с заявителем на кредит, с минимальным критериями, которым должен удовлетворять заявитель для получения кредита. Эти критерии могут касаться, например, минимального и максимального возраста заявителя, неприемлемой кредитной истории, минимальной и максимальной суммы кредита, максимального коэффициента loan-to-value (LTVs), максимального мультипликативного дохода, и порогов или cut-off точек кредитных баллов (points for the credit score). Обычно эти критерии определяются кредитором.
    • Доступность оценки: модель доступности услугиможет предоставлять такого рода услуги для определения того, когда заявитель может запросить кредит.
    Правила могут быть написаны в Drools Underwriting.drl как:
        rule "Age verification"
           when
               Borrower(age < 18)
               $loanApp : LoanApplication()
           then
               $loanApp.addFeedbackMessage(FeedbackMessages.MIN_AGE);
       end
    
       rule "Credit score"
    
           when
               Borrower(creditScore <= 600)
               $loanApp : LoanApplication()
           then
               $loanApp.addFeedbackMessage(FeedbackMessages.MIN_CREDIT_SCORE);
       end
    
       rule "Loan Amount limits"
           when
                   $loanApp : (LoanApplication(loanAmount <= 100000.0) or
                   LoanApplication(loanAmount >= 400000.0))
           then
               $loanApp.addFeedbackMessage(FeedbackMessages.LOAN_AMOUNT_LIMITS);
       end
    
       rule "Maximum Loan-to-value ratio"
           when
                   $loanApp : LoanApplication(loanToValueRatio > 80.0)
           then
               $loanApp.addFeedbackMessage(FeedbackMessages.LTV);
       end
    
       rule "Income multiples"
           salience -3
           when
               Borrower( $grossIncome : grossIncome )
                   Property( value > (new Double($grossIncome.doubleValue()*3)))
                   $loanApp : LoanApplication()
           then
               $loanApp.setAffordabilityFlag(Flag.NOT_AFFORDABLE);
       end
    
       rule "Affordability Model"
           salience -4
           when
                   Borrower( $affordableLoanAmount : affordableLoanAmount )
                   Property( value > (new Double($affordableLoanAmount.doubleValue())))
               $loanApp : LoanApplication()
           then
               $loanApp.setAffordabilityFlag(Flag.NOT_AFFORDABLE);
       end
  • Адекватная оценка недвижимости:Два соображения по адекватной оценке недвижимости.
    • Политические правила связанные с собственностью, такие как минимальные критерии который должна соответствовать собственность для предоставления кредита. Критерии могут включать, например, тип собственности, технологии строительства или материалов и сроков. Обычно эти критерии определяются кредитором, но могут также отражать требование страховщиков.
    • Оценка недвижимости: Сервис оценки недвижимостиможет предоставляет эту оценку путем использования различных методов для расчета стоимости собственности в качестве обеспечения ипотечной заявки.
    Правила могут быть написаны в Drools Underwriting.drl как:
            rule "Property type"
               when
                       Property(purpose != Flag.OWNER_OCCUPIED)
                       $loanApp : LoanApplication()
               then
                   $loanApp.addFeedbackMessage(FeedbackMessages.PROP_TYPE);
           end
    
           rule "Property age"
               when
                       Property(yearBuilt < 1965)
                       $loanApp : LoanApplication()
               then
                   $loanApp.addFeedbackMessage(FeedbackMessages.PROP_YEAR_BUILT);
           end



После вычисления правил оценки должно быть сформулировано решение по андеррайтингу и выдан результат. Используются следующие правила Decision.drl:
rule "Underwriting decision"

   when
       $loanApp : (LoanApplication(affordabilityFlag == Flag.NOT_AFFORDABLE) or
       LoanApplication( feedbackMsgSize > 0))
   then
       $loanApp.setStatus(Flag.FAILED);

end

Разрешение конфликтов

После того как все факты включены в рабочую память, где они могут быть изменены или отброшены, машина правил найдет все возможные соответствия правил фактам. Все правила кандидаты, найденные в ходе этого сопоставления добавляются в область выполнения машины правил. Область выполнения управляет порядком выполнения противоречивых правил используя стратегию урегулирования конфликтов. Урегулирование конфликтов необходимо когда существует несколько правил в области выполнения рабочих правил кандидатов для выполнения. Правила кандидаты на выполнение проверяются на на определение следующего набора правил действий для выполнения на основе заранее определенной схеме утверждений. После запуска правило может повлиять на состояние рабочей памяти, и машина правил должна знать в каком порядке они должны вызываться.
Drools использует различные стратегии разрешения конфликтов (смотрите в руководстве по Drools). Для этой статьи мы используем опорную (salience), наиболее часто используемую стратегию. Для этой стратегии, автор правила указывает, что это правило имеет более высокий приоритет чем другие соответствующие правила. Из всех соответствующих правил выбираются правила с наивысшим приоритетом.
При написании правил не следует делать предположений о том, в каком порядке будут вызываться правила после определенного потока. Это минимизирует необходимость прибегать с стратегиям разрешения конфликтов, описанным выше.
Проиллюстрируем как применяется стратегия разрешения конфликтов, например, при оценке доступности жилья, описанном ранее:
    rule "Income multiples"
       salience -3
       when
           Borrower( $grossIncome : grossIncome )
               Property( value > (new Double($grossIncome.doubleValue()*3)))
               $loanApp : LoanApplication()
       then
           $loanApp.setAffordabilityFlag(Flag.NOT_AFFORDABLE);
   end

   rule "Affordability Model"
       salience -4
       when
               Borrower( $affordableLoanAmount : affordableLoanAmount )
               Property( value > (new Double($affordableLoanAmount.doubleValue())))
           $loanApp : LoanApplication()
       then
           $loanApp.setAffordabilityFlag(Flag.NOT_AFFORDABLE);
   end
Для этой оценки кредиторы могут применять либо правила умножения доходов (income multiples rule) или правила модели доступности (affordability model rule). Модель правил доступности в результате может иметь значение превышающее показатель, полученный по правилу умножения доходов. Тогда кредиторы, как правило, не будут принимать во внимание эту оценку, и окончательная оценка будет делаться на основе модели правил умножения доходов. В Drools это достигается тем, что мы делаем правило умножения доходов более значимым.

Тестовый пример ипотечного андеррайтинга

Пример тестировался с использованием JBoss Drools 3.0.4 и JDK 1.5. Запуск теста JUnit показывает следующие результаты:
Testing successful application
=============================
Feedback message size=0
Affordability Flag=AFFORDABLE
Underwriting Decision=PASSED


Testing all feedback messages
=============================
Property should be built after 1965
Type of property should be Owner Occupied
Credit score should be greater than 600
Borrower minimum age should be 18
Loan to value ratio should not be greater than 80
Loan Amount should be between $100,000 and $400,000

Feedback message size=6
Affordability Flag=NOT_AFFORDABLE
Underwriting Decision=FAILED
На основе этих данных можно создать ответ и отобразить для последующего анализа.

Заключение

В этой статье я показал, как можно использовать машину правил Drools для сложных абстрактным бизнес-правил в сервисе, который может быть частью большой сервисной инфраструктуры. Сервис, автоматизирующий задачи ипотечного андеррайтинга был использован в качестве тематического исследовательского примера; подходы использованные в реализации этого сервиса можно применять во множестве других предметных областей, приспособленных к подходу основанному на правилах. Статья подчеркивает такие важные возможности машины правил Drools как: вынесение быстро-меняющихся бизнес-политик с использованием основанного на правилах программирования, правил вычисляющихся во время выполнения, и стратегии разрешения конфликтов. The article did not cover deployment considerations or change-management issues.

Ресурсы

Birali Hakizumwami сейчас работает архитектором приложений.

Комментариев нет:

Отправить комментарий