2016-11-07 21 views

回答

1

經過大量調查和多次嘗試,我得到了一個小型GRAILS3 API服務,通過它可以使用DROOLS引擎處理數據,而無需任何插件。所有這一切都是可能的,因爲DROOLS基於Java,並且由於GRAILS和Java之間的完美兼容。
所有你需要的是這樣的:

  1. 包括的build.gradle
  2. 最小的Drools依賴選擇一個文件夾來存儲files.drl
  3. 有一些實體事實的過程(不強制使用堅持他們,所以我跳過休眠配置)
  4. 實現一個服務來建立規則庫知識並獲得一個會話
  5. 實現一些方法到API控制器通過DROOLS處理數據(從服務獲得其會話)

下面有一種所有的一個簡單的例子:

Drools的依賴關係(在的build.gradle):

runtime "org.drools:drools-compiler:6.5.0.Final" 
compile "org.drools:drools-core:6.5.0.Final" 
compile "org.drools:knowledge-api:6.5.0.Final" 

DRL存儲在SRC /規則(參照該路徑將在該服務,見下文):myrules.drl

import my.entities.Book; 
import java.util.List; 

rule "Find author" 
    salience 10 
    when 
    $book: Book(author=="Shakespeare") 
    then 
    System.out.println("Book found, date:"+$book.getDate0()); 
end 

一些實體,例如圖書:

package my.entities 
import java.util.Date 

class Book { 
    String title, author 
    Date date0 
} 

服務建立Drools的知識和獲取會話(我準備了一個無狀態的發動機,比狀態一個打火機):

package my.services 
import grails.converters.* 

import org.kie.api.runtime.*; 
import org.kie.internal.io.ResourceFactory; 
import org.kie.api.*; 
import org.kie.api.io.*; 
import org.kie.api.builder.*; 

class DroolsService { 

def getSession() { 
     def path = "src/rules" 
     def lru = ["myrules.drl"] 
     def rules = [] 
     lru.each{ 
      rules.add("${path}${it}") 
     } 
     StatelessKieSession ksess = buildSession(rules) 
     return ksess 
    } 
} 

private buildSession(def lfile) { 
    println "Building DROOLS session..." 
    try { 
     def lres = [] 
     lfile.each{ 
      Resource resource = ResourceFactory.newFileResource(new File(it)); 
      lres.add(resource) 
     } 

     KieContainer kieContainer = buildKieContainer(lres) 
     StatelessKieSession kieSession = kieContainer.newStatelessKieSession() 
     return kieSession 
    } catch(Exception e) { 
     e.printStackTrace() 
     return null 
    } 

protected KieContainer buildKieContainer(def lres) { 
    KieServices kieServices = KieServices.Factory.get() 
    KieFileSystem kieFileSystem = kieServices.newKieFileSystem() 
    lres.each{ 
     kieFileSystem.write("src/main/resources/rule.drl", it) 
    } 

    KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem).buildAll() 
    Results results = kieBuilder.results 
    if (results.hasMessages(Message.Level.ERROR)) { 
     throw new IllegalStateException(this.class.name + ": " + results.messages.toString()) 
    } 
    KieContainer kieContainer = kieServices.newKieContainer(kieServices.repository.defaultReleaseId) 
    kieContainer 
} 

} 

而使用服務的API控制器:

class ApiController { 

def droolsService 

def proc = { 
    def sess = droolsService.getSession() 

    def mess = "ok DROOLS proc from JSON" 
    Book book = null 

    if (params.contbook) { 
     book = new Book(JSON.parse(params.contbook)) 
     sess.execute book 
    } 

    response.status = 200 
    render mess 
} 

在控制器I從參數中獲取json數據並由它們填充實體,以便使用由DROOLS服務初始化的規則引擎來執行它。當然這是一個非常簡單的解決方案,但它正在工作。

一些注意事項:

  • 每個DRL規則的RHS部分(後「再」)必須是Java,所以,在本例中,您不能訪問實體的直接私有財產,但你必須使用getter或setter(由GRAILS隱式創建)
  • getSession創建知識和新會話的新構建並且這不是最佳的,您可以重新設計它以存儲DROOLS會話,然後通過用戶重用它會話
  • 您可以在同一個文件夾中有多個files.drl,然後您必須在服務中列出所有這些文件才能使用pac k他們在知識引擎

希望這一切都有用。

相關問題