Drool与spring-boot的集成无法按预期工作

时间:2017-06-21 11:46:30

标签: spring-boot drools drools-kie-server

问题:规则( InterestRate .drl)在独立的java代码中被触发并给我准确的结果

package com.test.drool.config;

import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;

import com.test.drool.facts.InterestRate;

public class RunSampleInterestRate {

  public static void main(String[] args) {
    // TODO Auto-generated method stub


    KieContainer container= KieServices.Factory.get().getKieClasspathContainer();
InterestRate interestRate=new InterestRate();
interestRate.setLender("RBL");
System.out.println("printing session object before inserting"+interestRate.toString());

    KieSession kieSession=container.newKieSession("ksession-rules"); 
    kieSession.insert(interestRate);

    kieSession.fireAllRules();


        System.out.println(interestRate.getRate());


  }

}

给了我预期12.5的利率。

问题:我必须将其集成到休息服务中,并且我一直在尝试在休息环境下测试相同的逻辑并且它没有给我预期的结果。解雇规则后,服务 总是返回默认值0.0.My Environment是Spring-boot,drool是6.5.0 final。

POJO:

package com.test.drool.facts;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown=true)
public class InterestRate {

  @Override
  public String toString() {
    return "InterestRate [lender=" + lender + ", principal=" + principal + ", store=" + store
        + ", dealer=" + dealer + ", rate=" + rate + "]";
  }
  private String lender;
  private String principal;
  private String store;
  private String dealer;
  private double rate;
  public double getRate() {
    return rate;
  }
  public void setRate(double rate) {
    this.rate = rate;
  }
  public String getLender() {
    return lender;
  }
  public void setLender(String lender) {
    this.lender = lender;
  }
  public String getPrincipal() {
    return principal;
  }
  public void setPrincipal(String principal) {
    this.principal = principal;
  }
  public String getStore() {
    return store;
  }
  public void setStore(String store) {
    this.store = store;
  }
  public String getDealer() {
    return dealer;
  }
  public void setDealer(String dealer) {
    this.dealer = dealer;
  }
}

Bean配置

package com.test.drool.config;

import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class DroolDependencyConfig {
@Bean(name="kieContainer")
  public KieContainer kieContainer() {
   return KieServices.Factory.get().getKieClasspathContainer();
  }
}

控制器:

package com.test.drool.controllers;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.test.drool.facts.InterestRate;
import com.test.drool.service.RuleExecuteService;

@RestController
@RequestMapping(value="/rule")
public class RuleExecuteController {
@Autowired
  private RuleExecuteService executeService;
private static Logger logger=LoggerFactory.getLogger(RuleExecuteController.class);


 @PostMapping(value = "/execute", consumes = MediaType.APPLICATION_JSON_VALUE,produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Double> getInterestRate(@RequestBody InterestRate interestRate){
   logger.info(String.format("logging Request Object %s",interestRate.toString()));
    return new ResponseEntity<Double>(executeService.executeRule(interestRate),HttpStatus.OK);
  }
}

RuleServiceImpl:

package com.test.drool.service.impl;

import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.test.drool.facts.InterestRate;
import com.test.drool.service.RuleExecuteService;
@Service
public class RuleExecutorServiceImpl implements RuleExecuteService {
private KieContainer kieContainer;
private static org.slf4j.Logger logger=LoggerFactory.getLogger(RuleExecutorServiceImpl.class);
@Autowired
public RuleExecutorServiceImpl(KieContainer kieContainer) {
this.kieContainer=kieContainer;   
  }
  @Override
  public double executeRule(InterestRate interestRate) {
      logger.info("firing up session and executing rules");

       KieSession  kieSession= kieContainer.newKieSession("ksession-rules");
          logger.info("Printing object before inserting in session"+interestRate.toString());
       kieSession.insert(interestRate);
       kieSession.fireAllRules();
       System.out.println("returning values from rule execution"+">>>"+interestRate.getRate());
       return interestRate.getRate();
  }

}

DRL文件:

package com.test.drool.facts

rule "Interest Rate"
when
    $interestrate := InterestRate(lender.equals("RBL"))  
then
$interestrate.setRate(12.30);

end

Gradle依赖:

dependencies {
 compile "org.kie:kie-spring:${droolsVersion}"
 compile "org.kie:kie-api:${droolsVersion}"
 compile "org.drools:drools-core:${droolsVersion}"
 compile "org.drools:drools-compiler:${droolsVersion}"
//compile('org.springframework.cloud:spring-cloud-starter-eureka')
    compile('org.springframework.boot:spring-boot-starter-actuator')
    compile ('org.springframework.boot:spring-boot-starter-web')
       compile ('org.springframework.boot:spring-boot-starter-data-rest')
   compile ('org.springframework.boot:spring-boot-devtools')
    testCompile('org.springframework.boot:spring-boot-starter-test')
    compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.2'
    compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.0'
}

1 个答案:

答案 0 :(得分:0)

我不知道它为什么会起作用,但我们在gradle文件中保持最小的春天流口水。我和我的同事所做的只是在gradle中只有kie-spring和drool-compiler,它就像一个魅力。我们还需要排除一些弹簧模块,因为弹簧开关1.5不适用于kie所依赖的弹簧3.2。对于未来的弹簧靴流口水开发,这里是gradle。只需粘贴它,然后构建和编码,就像为任何其他spring-boot项目编写代码一样。

repositories {
    mavenCentral()
    maven {
        name 'jboss'
        url 'http://repository.jboss.org/nexus/content/groups/public-jboss'
    }
}
buildscript {
    ext {
        springBootVersion = '1.5.3.RELEASE'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'

version = '0.0.1'
sourceCompatibility = 1.8
targetCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencyManagement {
    imports {
        mavenBom 'org.springframework.cloud:spring-cloud-dependencies:Camden.SR6'
    }
}
dependencies {
    compile ('org.kie:kie-spring:6.5.0.Final'){
        exclude group:'org.springframework', module: 'spring-core'
        exclude group:'org.springframework', module: 'spring-tx'
        exclude group:'org.springframework', module: 'spring-beans'
        exclude group:'org.springframework', module: 'spring-context'
    }
    compile "org.drools:drools-compiler:6.5.0.Final"
    compile ('org.springframework.boot:spring-boot-starter-web')
    compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.0'

}
task createFolder{
  def configDir = new File(project.buildDir.path+"/libs", "config")
  def keystoreDir = new File(project.buildDir.path+"/libs", "keystore")
  def logDir = new File(project.buildDir.path+"/libs", "log")
  def libDir = new File(project.buildDir.path+"/libs", "lib")

  if(!logDir.exists()){
    logDir.mkdirs()
  }
  delete configDir
  delete libDir
  delete keystoreDir

  libDir.mkdirs()
  configDir.mkdirs()
  keystoreDir.mkdirs()
}

 //copy config
task copyConfig(type: Copy) {   
    into project.buildDir.path+"/libs/config"
    from "config"

}
 //copy keystore
task copyKeystore(type: Copy) { 
    into project.buildDir.path+"/libs/keystore"
    from "keystore"
}

//copy dependencies
task copyRuntimeLibs(type: Copy) {
    into project.buildDir.path+"/libs/lib"
    from configurations.compile

}

task bundleAll(type: Jar){
    dependsOn 'createFolder', 'copyRuntimeLibs', 'copyConfig', 'copyKeystore' 

    manifest { 
        def manifestClasspath = configurations.compile.collect { "lib/" + it.getName() }.join(' ') 
        attributes 'Implementation-Title': 'rule-service', 
                   'Implementation-Version': version,
                   'Main-Class': 'com.test.drool.starte.RuleStarter',
                   'Class-Path': manifestClasspath
    }  
    baseName=project.name
  from { (configurations.compile - configurations.compile).collect { it.isDirectory() ? it : zipTree(it) } }
  with jar
     exclude 'META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA' 
} 

task zip(type: Zip){
    dependsOn 'bundleAll'
     from 'build/libs'
}