Можно ли использовать двигатель drools rule в GRAILS3 без установки плагина? Я прошу, потому что я знаю, что слюни реализованы в java, и actual official plugin от Ken Siprell для GRAILS (по-видимому) больше не работает.Как использовать слюни в grails3 без плагина?
ответ
После долгих исследований и многочисленных попыток я получил небольшую услугу API GRAILS3, через которую можно обрабатывать данные с помощью движка DROOLS без какого-либо плагина. Все это возможно, потому что DROOLS базируется на java и благодаря совершенной совместимости между GRAILS и Java.
Все, что вам нужно следующее:
- включают минимальную зависимость Drools в build.gradle
- выбрать папку для хранения files.drl
- есть некоторые объекты, чтобы использовать в качестве фактов к процессу (не обязательно сохраняются их, поэтому я пропущу конфигурации спящего режима)
- реализовать услугу для создания правила базы знаний и получить сеанс
- реализовать некоторые методы в контроллер 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"
ДРЛ в 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
}
В контроллер я беру данные json из параметра и заполняю им сущность, чтобы выполнить его с помощью механизма правил, инициализированного службой DROOLS. Конечно, это очень простое решение, но оно работает.
Некоторые примечания:
- РИТ часть каждого правила DRL (после того, как «то») должен быть Java, так, как в примере, вы не можете получить доступ непосредственно частной собственностью компании, но вы должны использовать геттер или сеттер (неявно созданный GRAILS)
- getSession создает новую сборку знаний и новый сеанс, и это не оптимально, вы можете переделать его, чтобы сохранить сеанс DROOLS, а затем повторно использовать его через пользователя session
- у вас может быть несколько files.drl в той же папке, а затем вы должны перечислить их все в службе, чтобы pac k их в знании двигателя
Надеюсь, все это полезно.