Plugins 如何在没有任何插件的情况下使用grails3中的drools?

Plugins 如何在没有任何插件的情况下使用grails3中的drools?,plugins,drools,grails3,Plugins,Drools,Grails3,在GRAILS3中不安装任何插件就可以使用drools规则引擎吗?我问这个问题是因为我知道drools是用java实现的,Ken Siprell为GRAILS提供的服务(显然)已经不起作用了。经过多次调查和尝试,我得到了一个小型GRAILS3 API服务,通过该服务,可以使用drools引擎处理数据,而无需任何插件。这一切都是可能的,因为DROOLS基于java,而且GRAILS和java之间具有完美的兼容性 您只需要以下内容: 在build.gradle中包含最小的DROOLS依赖项 选择用于

在GRAILS3中不安装任何插件就可以使用drools规则引擎吗?我问这个问题是因为我知道drools是用java实现的,Ken Siprell为GRAILS提供的服务(显然)已经不起作用了。

经过多次调查和尝试,我得到了一个小型GRAILS3 API服务,通过该服务,可以使用drools引擎处理数据,而无需任何插件。这一切都是可能的,因为DROOLS基于java,而且GRAILS和java之间具有完美的兼容性
您只需要以下内容:

  • 在build.gradle中包含最小的DROOLS依赖项
  • 选择用于存储文件的文件夹。drl
  • 有一些实体要用作要处理的事实(不强制保留它们,所以我跳过hibernate配置)
  • 实现一个服务以构建规则库知识并获得会话
  • 在API控制器中实现一些方法,通过DROOLS处理数据(从服务中获得会话)
  • 下面是一个简单的例子:

    DROOLS依赖项(在build.gradle中):

    src/rules中的DRL存储(服务中将引用此路径,请参见下文):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知识和获取会话的服务(我准备了一个无状态引擎,比有状态引擎轻):

    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
    }
    
    在控制器中,我从参数中获取json数据并用它们填充实体,以便使用DROOLS服务初始化的规则引擎执行它。当然,这是一个非常简单的解决方案,但它正在发挥作用

    一些注意事项:

    • 每个drl规则的RHS部分(在“then”之后)必须是java,因此,如示例中所示,您不能直接访问实体的私有属性,但必须使用getter或setter(由GRAILS隐式创建)
    • getSession创建一个新的知识构建和一个新会话,但这不是最优的,您可以重新设计它以存储DROOLS会话,然后通过用户会话重用它
    • 您可以在同一文件夹中有多个文件.drl,然后必须在服务中列出所有文件,以便将它们打包到知识引擎中
    希望一切都有用

    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
    }
    
    }
    
    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
    }