Spring boot 与弹簧靴的Drool集成未按预期工作

Spring boot 与弹簧靴的Drool集成未按预期工作,spring-boot,drools,drools-kie-server,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 Run

问题:规则(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的预期利率

问题:我必须将其集成到rest服务中,并且我一直在尝试在rest环境下测试相同的逻辑,但它并没有给我预期的结果 始终返回默认值0.0。我的环境是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;
  }
}
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);
  }
}
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();
  }

}
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.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;
  }
}
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);
  }
}
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;

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;
  }
}
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);
  }
}
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();
  }

}
包com.test.drool.facts

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

end
渐变依赖性:

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

我不知道它工作的原因,但我们在gradle文件中保留了最小的spring drool。我和我的同事所做的只是在gradle中只有kie spring和drool编译器,它工作得很好。我们还需要排除spring的一些模块,因为spring boot 1.5不能与kie所依赖的spring 3.2一起工作。为了将来的spring bootdrool development,这是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'
}

您在RBL中传递的贷方是谁?你能添加你的日志吗?是的,我添加了日志,并确认RBL作为一个值正在从我的rest控制器传递回我的服务,并在其中注入到rulesession。我的意思是在你的问题中添加你的日志输出。请更改您的规则并删除贷方.equals(“RBL”)部分,然后查看您的规则是否触发。我想问题就在附近规则中的
:=
看起来很有趣。一个
就足够了。另外,
leander==“RBL”
是编写这篇文章的标准方式。我做了这些更改,但问题仍然是,为什么同一个drl文件可以从独立的程序中很好地执行,而不是从Spring应用程序中执行。这就是问题的症结所在。kissession是我们执行规则所需要的全部。不确定我是否遗漏了一些东西。