Jess Rule Engine a JSR 94

1. Prehľad

Používanie pravidla je vynikajúci spôsob, ako oddeliť obchodnú logiku od nášho štandardného kódu a chrániť náš aplikačný kód pred obchodnými zmenami.

V predchádzajúcom článku o Java Rule Engines sme sa zmienili o špecifikácii JSR 94. Jess Rule Engine má mimoriadny významako implementácia ovládača referenčných pravidiel pre JSR 94, tak sa na to pozrime.

2. Jess Rule Engine

Jess je jedným z prvých motorov pravidiel, ktoré sa dajú ľahko integrovať do Javy. Jess používa vylepšenú implementáciu vysoko efektívneho algoritmu Rete, ktorý je pre väčšinu scenárov oveľa rýchlejší ako jednoduchá slučka Java.

Pravidlá je možné vykonávať z množín pravidiel napísaných v natívnom jazyku Jess Rules, rozšírenej syntaxe založenej na Lisp, alebo z podrobnejšieho formátu XML. Použijeme natívny formát.

Existuje vývojové prostredie založené na Eclipse (pre staršie verzie Eclipse) a vynikajúca dokumentácia o používaní a integrácii Jess s Javou. Existuje dokonca aj rozhranie príkazového riadku REPL, kde si môžeme vyskúšať svoje nápady pred vytvorením súboru s pravidlami.

Ako motor referenčných pravidiel pre JSR 94 je Jess podľa definície kompatibilný s JSR 94, aj keď už nie je v aktívnom vývoji.

2.1. Stručné slovo o JSR 94

JSR 94 poskytuje API, ktoré môžeme použiť na to, aby sme získali nezávislosť od ktoréhokoľvek nástroja pre pravidlá, ktorý si vyberieme. Môžeme zapojiť akýkoľvek modul pravidiel vyhovujúci JSR 94 do nášho kódu a spustiť niektoré pravidlá bez toho, aby sme museli meniť spôsob našej interakcie s motorom pravidiel v našej aplikácii.

To neznamená, že základné pravidlá nástroja na pravidlá budú vyzerať rovnako - možno ich budeme musieť prepísať, ak zmeníme modul pravidiel, ale znamená to, že na to, aby sme mohli používať nový modul pravidiel, nebudeme musieť prepísať časti našej aplikácie. Jediné zmeny kódu, ktoré budeme potrebovať, je aktualizácia názvu ovládača a niektorých názvov súborov pravidiel.

2.2. Vodič Jess JSR 94

Aj keď existuje motor referenčných pravidiel vodič pre Jess zahrnutý pre JSR 94, samotný Jess nie je zahrnutý, pretože je to licenčný komerčný produkt. Referenčný ovládač sa nachádza v org.jcp.jsr94.jess balíček, ale novší ovládač je k dispozícii v jess.jsr94 balíček, keď si stiahneme Jess.

Začnime tým, že sa pozrieme na Jessovu natívnu integráciu Java, skôr ako sa pozrieme na to, ako to zmení vrstva JSR 94.

3. Poskytnuté príklady

Než začneme integrovať Jess do nášho kódu, uistite sa, že sme si ho stiahli a sprístupnili na našej triednej ceste. Ak už nemáme licenciu, budeme sa musieť zaregistrovať na bezplatné 30-dňové bezplatné stiahnutie.

Stiahnime teda Jess, rozbalené stiahnite Jess71p2.jara spustením jedného z jeho príkladov sa ubezpečte, že máme funkčnú verziu.

3.1. Samostatná Jess

Pozrime sa na Jess71p2 / príklady adresár, kde jess adresár obsahuje niektoré vzorové sady pravidiel. The pricing_engine adresár zobrazuje integráciu, ktorú je možné vykonať pomocou mravca build.xml scenár. Zmeňme náš adresár na príklad cenového modulu a spustime program cez test mravca:

cd Jess71p2 / examples / pricing_engine test mravcov

Takto sa zostaví a spustí ukážka cenovej pravidlá:

Buildfile: Jess71p2 \ examples \ pricing_engine \ build.xml ... test: [java] Položky pre objednávku 123: [java] 1 CD Writer: 199,99 ... [java] Položky pre objednávku 666: [java] 1 DVD Incredibles: 29,99 [java] Ponuky na objednávku 666: [java] BUILD SUCCESSFUL Celkový čas: 1 sekunda

3.2. Jess S JSR 94

Teraz, keď pracujeme s Jess, stiahneme si JSR 94 a potom ho rozbalíme a vytvoríme adresár jsr94-1.0 s adresármi ant, doc, lib a src vo vnútri.

rozbaľte jreng-1_0a-fr-spec-api.zip

Toto nám dáva referenčné ovládače API JSR 94 a Jess, ale neprichádza s licencovanou implementáciou Jess, takže ak sa teraz pokúsime spustiť príklad, zobrazí sa nasledujúca chyba:

Chyba: Referenčnú implementáciu Jess sa nepodarilo nájsť.

Pridajme teda referenčnú implementáciu Jess, jess.jar, ktoré vyšli ako súčasť súboru Jess71p2, ktorý sme si predtým stiahli a skopírovali do adresára JSR 94 lib, potom spustime príklad:

cp Jess71p2 / lib / jess.jar jsr94-1.0 / lib / java -jar jsr94-1.0 / lib / jsr94-example.jar

V príklade sú uvedené niektoré pravidlá na určenie zostávajúceho kreditu zákazníka pri úhrade faktúr:

Administrátorské rozhranie Acquired RuleAdministrator: [chránené e-mailom] ... Runtime API získané RuleRuntime: [chránené e-mailom] Výsledok limitu úveru zákazníka: 3000 ... Suma faktúry 2: 1750 stav: platená Uvoľnená relácia Stateful Rule.

4. Integrácia Jess s Javou

Teraz, keď sme si stiahli Jess a JSR 94 a spustili sme niektoré pravidlá natívne aj prostredníctvom JSR, sa pozrime na to, ako integrovať sadu pravidiel Jess do programu Java.

V našom príklade začneme vykonaním jednoduchého súboru s pravidlami Jess, ahojjess.clp, z kódu Java a potom sa pozrite na iný súbor s pravidlami, bonus.clp, ktorá použije a upraví niektoré z našich objektov.

4.1. Maven závislosť

Pre Jess nie je k dispozícii žiadna závislosť od Maven, takže ak sme tak ešte neurobili, stiahneme a rozbalíme nádobu Jess (jess.jar) a inštalácia mvn do nášho miestneho úložiska Maven:

inštalácia mvn: install-file -Dfile = jess.jar -DgroupId = gov.sandia -DartifactId = jess -Dversion = 7.1p2 -Dpackaging = jar -DgeneratePom = true

Potom ho môžeme pridať ako závislosť obvyklým spôsobom:

 gov.sandia jess 7.1p2 

4.2. Ahoj Jess súbor s pravidlami

Ďalej vytvoríme najjednoduchšie súbory s pravidlami na vytlačenie správy. Uložíme súbor s pravidlami ako ahojjess.clp:

(výtlačok „Hello from Jess!“ crlf)

4.3. Jess Rule Engine

Teraz vytvorme inštanciu Jess Rete pravidlo motora, reset () do pôvodného stavu, nahrajte pravidlá do ahojjess.clpa spustite ich:

public class HelloJess {public static void main (String [] args) throws JessException {Rete engine = new Rete (); resetovanie motora (); engine.batch ("hellojess.clp"); engine.run (); }

Pre tento jednoduchý príklad sme práve pridali potenciál JessException k nášmu hlavný metóda hodí doložka.

Keď spustíme náš program, uvidíme výstup:

Ahoj od Jess!

5. Integrácia Jess do Javy s dátami

Teraz, keď je všetko správne nainštalované a môžeme spúšťať pravidlá, Pozrime sa, ako pridáme údaje na spracovanie pravidla a ako načítame výsledky.

Najskôr budeme potrebovať niekoľko tried Java, aby sme s nimi mohli pracovať, a potom novú sadu pravidiel, ktorá ich používa.

5.1. Model

Vytvorme niekoľko jednoduchých Otázka a Odpoveď triedy:

public class Question {private String question; zostatok súkromného int;  // getre a setre  verejna otazka (strunova otazka, int balance) {this.question = question; this.balance = zostatok; }} verejná trieda Odpoveď {private String answer; private int newBalance;  // getre a setre  verejná odpoveď (reťazcová odpoveď, int newBalance) {this.answer = odpoveď; this.newBalance = newBalance; }}

5.2 Pravidlo Jess so vstupom a výstupom

Teraz vytvorme jednoduchú Jessovu sadu pravidiel s názvom bonus.clp že minieme a Otázka dostať a dostať Odpoveď od.

Najprv my dovoz náš Otázka a Odpoveď triedy a potom použite Jessove deftemplate ich sprístupnenie motoru pravidiel:

(import com.baeldung.rules.jsr94.jess.model. *) (deftemplate Question (declare (from-class Question)))) (deftemplate Answer (declare (from-class Answer))))

Všimnite si použitie zátvoriek, ktoré označujú volania funkcií Jess.

Teraz poďme defrulovať pridať jedno pravidlo vyhnúť sa prečerpaniu v Jessovom rozšírenom formáte Lisp, ktorý nám dáva bonus 50 dolárov, ak je zostatok v našom Otázka je pod nulou:

(zrušiť kontokorentné prečerpanie „Dať 50 dolárov každému prečerpanému“? q <- (Otázka {zostatok (pridať (nová odpoveď „Bonus za prečerpanie“ (+? q.zostatok 50)))))

Tu sa zobrazuje „?” viaže objekt na premennú q keď sú podmienky na pravej strane „<-“ zápas. V takom prípade to je, keď motor pravidiel nájde a Otázka ktorá má a rovnováha menej ako 0.

Keď sa to stane, potom akcie napravo od „=>” sú spustené tak motor pridaťs a nová odpoveď objekt do pracovnej pamäte. Dali sme mu dva požadované argumenty konštruktora: „Bonus za prečerpanie“ pre odpoveď parameter a a (+) funkcia na výpočet novýMnožstvo parameter.

5.3. Manipulácia s údajmi pomocou nástroja Jess Rule Engine

Môžeme použiť pridať () pridať jeden objekt naraz do pracovnej pamäte nášho pravidla engine, alebo pridať všetko() pridať zbierku údajov. Poďme použiť pridať () pridať jednu otázku:

Otázka otázka = nová Otázka („Môžem mať bonus?“, -5); engine.add (údaje);

Po zavedení všetkých našich údajov vykonajme naše pravidlá:

engine.run ();

Jess Rete motor bude pracovať svoje kúzlo a vráti sa, keď sa vykonajú všetky príslušné pravidlá. V našom prípade budeme mať Odpoveď preskúmať.

Použime a jess.Filter extrahovať naše Odpoveď z pravidla motora do Iterable objekt výsledkov:

Výsledky iterátora = engine.getObjects (nový jess.Filter.ByClass (Answer.class)); while (results.hasNext ()) {Answer answer = (Answer) results.next (); // spracovať našu odpoveď}

V našom jednoduchom príklade nemáme žiadne referenčné údaje, ale keď tak urobíme, môžeme použiť a WorkingMemoryMarker a značka motora () na označenie stavu pracovnej pamäte motora pravidla po pridaní údajov. Potom môžeme zavolať motor.resetToMark s našou značkou obnovíme pracovnú pamäť na náš „načítaný“ stav a efektívne znovu použijeme motor pravidiel pre inú sadu objektov:

Značka WorkingMemoryMarker; // načítanie referenčných údajov značka = engine.mark (); // načítanie konkrétnych údajov a spustenie pravidiel engine.resetToMark (značka);

Poďme sa teraz pozrieť na to, ako spúšťame tú istú množinu pravidiel pomocou JSR 94.

6. Používanie JSR 94 na integráciu Jess Rule Engine

JSR 94 štandardizuje, ako náš kód interaguje s motorom pravidiel. Ak sa objaví lepšia alternatíva, uľahčí to zmenu nášho pravidla bez výraznej zmeny aplikácie.

Rozhranie JSR 94 API sa dodáva v dvoch hlavných balíkoch:

  • javax.rules.admin - pre načítanie vodičov a pravidlá
  • javax.rules - spustiť pravidlá a extrahovať výsledky

Pozrime sa, ako používať triedy v obidvoch týchto triedach.

6.1. Maven závislosť

Najskôr pridajme závislosť Maven pre jsr94:

 jsr94 jsr94 1.1 

6.2. Administration API

Ak chcete začať používať JSR 94, musíme vytvoriť inštanciu a RuleServiceProvider. Vytvorme jeden a odovzdajme ho nášmu ovládaču pravidiel Jess:

Reťazec RULE_SERVICE_PROVIDER = "jess.jsr94"; Class.forName (RULE_SERVICE_PROVIDER + ".RuleServiceProviderImpl"); RuleServiceProvider ruleServiceProvider = RuleServiceProviderManager.getRuleServiceProvider (RULE_SERVICE_PROVIDER);

Poďme na Jessovu JSR 94 RuleAdministrator, načítajte náš vzorový súbor pravidiel do JSR 94 RuleExecutionSet, a zaregistrujte ho na vykonanie pomocou URI podľa nášho výberu:

RuleAdministrator ruleAdministrator = serviceProvider.getRuleAdministrator (); InputStream ruleInput = JessRunner.class.getResourceAsStream (rulesFile); HashMap vendorProperties = nový HashMap (); RuleExecutionSet ruleExecutionSet = ruleAdministrator .getLocalRuleExecutionSetProvider (vendorProperties) .createRuleExecutionSet (ruleInput, vendorProperties); Reťazec rulesURI = "rules: // com / baeldung / rules / bonus"; ruleAdministrator.registerRuleExecutionSet (rulesURI, ruleExecutionSet, vendorProperties);

Vodič Jess nepotrebuje vendorProperties mapa, ktorú sme dodali RuleAdministrator, ale je to súčasť rozhrania a môžu to vyžadovať iní dodávatelia.

Teraz, keď bol inicializovaný náš poskytovateľ nástroja na pravidlá Jess a naša sada pravidiel bola zaregistrovaná, sme takmer pripravení naše pravidlá spustiť.

Aby sme ich mohli spustiť, potrebujeme inštanciu runtime a reláciu, aby sme ich mohli spustiť. Pridajme tiež zástupný symbol, CalcResults (), kde sa mágia stane, a uvoľnite reláciu:

RuleRuntime ruleRuntime = ruleServiceProvider.getRuleRuntime (); StatelessRuleSession statelessRuleSession = (StatelessRuleSession) ruleRuntime.createRuleSession (rulesURI, new HashMap (), RuleRuntime.STATELESS_SESSION_TYPE); CalcResults (statelessRuleSession); statelessRuleSession.release ();

6.3. Execution API

Keď už máme všetko pripravené, zrealizujme to CalcResults aby sme poskytli naše počiatočné údaje, vykonali naše pravidlá v relácii bez štátnej príslušnosti a extrahovali výsledky:

Zoznam údajov = nový ArrayList (); data.add (nová otázka („Môžem mať bonus?“, -5)); Zoznam výsledkov = statelessRuleSession.executeRules (data);

Pretože JSR 94 bol napísaný pred JDK 5, API nepoužíva všeobecné, takže poďme len použiť Iterátor zobraziť výsledky:

Iterátor itr = results.iterator (); while (itr.hasNext ()) {Object obj = itr.next (); if (obj instanceof Answer) {int answerBalance = ((Answer) obj) .getCalculatedBalance ()); }}

V našom príklade sme použili reláciu bez štátnej príslušnosti, ale môžeme tiež vytvoriť a StatefuleRuleSession ak chceme zachovať stav medzi invokáciami.

7. Záver

V tomto článku sme sa naučili, ako integrovať nástroj Jessových pravidiel do našej aplikácie pomocou Jessových natívnych tried a s trochou úsilia pomocou JSR 94. Videli sme, ako možno obchodné pravidlá rozdeliť do samostatných súborov, ktoré sa majú spracovať motorom pravidiel, keď je naša aplikácia spustená.

Ak máme pravidlá pre rovnakú obchodnú logiku napísané pre iný modul pravidiel vyhovujúci JSR 94, potom môžeme jednoducho pridať ovládač pre náš alternatívny nástroj pravidiel a aktualizovať názov ovládača, ktorý by mala naša aplikácia používať, a nemali by sa robiť ďalšie zmeny kódu. nevyhnutné.

Na serveri jess.sandia.gov nájdete viac podrobností o vkladaní Jess do aplikácie Java a Oracle má užitočného sprievodcu Začíname s rozhraním Java Rule Engine API (JSR 94).

Ako obvykle je kód, ktorý sme si preštudovali v tomto článku, k dispozícii na GitHub.