Drools规则3次后没有被解雇

时间:2015-01-09 01:01:47

标签: java drools

我创建了一个知识库,然后在循环中使用知识库来创建

  • 无国籍知识会议
  • 并在会话上调用execute,为每次迭代使用相同的数据。

-----这是主要功能------

 public static final void main(String[] args)
  {
    KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
    kbuilder.add(ResourceFactory.newClassPathResource("diskRules.drl"), ResourceType.DRL);
    if (kbuilder.hasErrors())
    {

      System.err.println(kbuilder.getErrors().toString());

    }

    KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();

    kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());

    CollectorPluginData cpd = getData();

    for (int i = 0; i < 10; i++)
    {

      System.out.println("Iteration number: " + i);
      StatelessKnowledgeSession ksession = kbase.newStatelessKnowledgeSession();

      ksession.execute(cpd);
    }

---------这是drl文件

rule "Disk State: Unconfigured Bad-ERROR"
when
    $diskData : CollectorPluginData(pluginName == "DiskCollectorPlugin", $componentList : componentList)
    $component: Component( type == "Disk"
        && ((properties contains "eventType" && properties["eventType"] == "PD Event" 
              && properties contains "newComponentState"&& properties["newComponentState"] == "Unconfigured Bad") 
            || (properties contains "scsiDeviceType" && properties["scsiDeviceType"] == "Disk" 
              && properties contains "currentComponentState" && properties["currentComponentState"] == "Unconfigured Bad"))
        ) from $componentList  
then

    System.out.println("Rule Fired");
end
rule "Disk State: Unconfigured Bad-OK"
when
    $diskData : CollectorPluginData(pluginName == "DiskCollectorPlugin", $componentList : componentList)
    $component: Component( type == "Disk"
        && ((properties contains "eventType" && properties["eventType"] == "PD Event" 
              && properties contains "newComponentState"&& properties["newComponentState"] != "Unconfigured Bad") 
            || (properties contains "scsiDeviceType" && properties["scsiDeviceType"] == "Disk" 
              && properties contains "currentComponentState" && properties["currentComponentState"] != "Unconfigured Bad"))
        ) from $componentList  
then

    System.out.println("Rule Fired");
end

对于每次迭代,相同的数据用于执行会话,因此预期会执行相同的规则集,但是在一些迭代后我观察到没有规则被触发。

以下是每次迭代的控制台输出:

Iteration number: 0
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Iteration number: 1
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Iteration number: 2
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Rule Fired
Iteration number: 3
Iteration number: 4
Iteration number: 5
Iteration number: 6
Iteration number: 7
Iteration number: 8
Iteration number: 9

一些观察结果:

  • 在每个规则中,我都有$ componentList用于匹配,当我们减少组件列表中的组件数量时,需要更多的迭代才能达到没有触发规则的情况。

  • 当我们将规则文件中的条件更改为simple(下面提到)时,每次迭代都会生成相同的输出。

    $ component:$ componentList

  • 中的组件(类型==“磁盘”)

这看起来像drools,某种内存或数据结构损坏的问题。

我也尝试过使用statefull会话并看到相同的行为。

我在这里遗漏了什么吗?我的理解是知识库是一种只读,我们可以从中创建任意数量的会话。

这里是5.6.0.Final版本正在使用,也试过了drools 6.1.0但看到了同样的行为。

我因为这个问题而陷入困境,会感激任何帮助。

如果您希望在类定义后帮助重现此问题

MainClass.java
    package com.test
    import com.test.CollectorPluginData;
    import com.test.Component;

    import java.util.ArrayList;
    import java.util.List;
    import java.util.Random;

    import org.drools.KnowledgeBase;
    import org.drools.KnowledgeBaseFactory;
    import org.drools.builder.KnowledgeBuilder;
    import org.drools.builder.KnowledgeBuilderFactory;
    import org.drools.builder.ResourceType;
    import org.drools.io.ResourceFactory;
    import org.drools.runtime.StatelessKnowledgeSession;

    public class MainClass
    {
      public static final void main(String[] args)
      {
        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
        kbuilder.add(ResourceFactory.newClassPathResource("diskRules.drl"), ResourceType.DRL);
        if (kbuilder.hasErrors())
        {

          System.err.println(kbuilder.getErrors().toString());

        }

        KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();

        kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());

        CollectorPluginData cpd = getData();

        for (int i = 0; i < 10; i++)
        {

          System.out.println("Iteration number: " + i);
          StatelessKnowledgeSession ksession = kbase.newStatelessKnowledgeSession();

          ksession.execute(cpd);
        }
      }

      public static CollectorPluginData getData()
      {

        CollectorPluginData cpd = new CollectorPluginData();

        cpd.setPluginName("DiskCollectorPlugin");

        List<Component> components = getDiskComponets("Online", 5);
        components.addAll(getDiskComponets("Unconfigured Good", 5));
        components.addAll(getDiskComponets("Unconfigured Bad", 5));
        components.addAll(getDiskComponets("Offline", 5));
        components.addAll(getDiskComponets("Failed", 5));
        cpd.setComponentList(components);

        return cpd;

      }

      private static List<Component> getDiskComponets(String status, int num)
      {
        List<Component> components = new ArrayList<Component>();
        int enclosure = new Random().nextInt();
        for (int i = 0; i < num; i++)
        {
          Component c = new Component();
          c.setType("Disk");
          c.setName("Enclosure " + enclosure + " Disk " + String.valueOf(i + 1));
          c.setId(enclosure + "_" + String.valueOf(i + 1));
          c.setproperty("isSupported", 1);
          c.setproperty("pdMediaType", "Rotating Media, HDD");
          c.setproperty("mediaErrorCount", 0);
          c.setproperty("scsiDeviceType", "Disk");
          c.setproperty("lastFailedPredEventSeqNum", 0);
          c.setproperty("currentComponentState", status);
          c.setproperty("otherErrorCount", 0);
          c.setproperty("isGlobalHotSpare", 0);
          c.setproperty("isForcedPdGuid", 0);
          c.setproperty("maxSupportedSpeed", "6G");
          c.setproperty("isDedicatedHotSpare", 0);
          c.setproperty("isForeign", 0);
          c.setproperty("predFailCount", 0);
          c.setproperty("driveReadyForRemoval", 0);
          c.setproperty("linkSpeed", 3);
          c.setproperty("isPdInVd", 0);
          c.setproperty("pdDeviceType", "SAS");
          c.setproperty("rawSize", 1953525168);
          c.setproperty("enclosureId", 252);
          c.setproperty("nonCoercedSize", 1952476592);
          c.setproperty("coercedSize", 1951170560);
          c.setproperty("temperatureInCelsius", 255);
          c.setproperty("slotNumber", 2);
          c.setproperty("pdPowerState", "Spun Down");
          c.setproperty("shieldCounter", 0);
          c.setproperty("shieldDiagCompletionTime", "0000-00-00T00:00:00");
          components.add(c);
        }
        return components;
      }
    }

Component.java

 package com.test;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;

import java.util.HashMap;
import java.util.Map;

public class Component
{
  protected String type;
  protected String id; 
  protected String name; 

  protected Map<String, Object> properties;

  public String getType()
  {
    return type;
  }

  public void setType(String type)
  {
    this.type = type;
  }

  public Map<String, Object> getProperties()
  {
    return properties;
  }

  public void setProperties(Map<String, Object> properties)
  {
    this.properties = properties;
  }

  public void setproperty(String key, Object value)
  {
    if (this.properties == null)
    {
      this.properties = new HashMap<String, Object>();
    }

    this.properties.put(key, value);

  }

  public Component()
  {
    super();

  }

  public Component(String type, String id, int status)
  {

    this.type = type;
    this.id = id;
    setproperty("status", status);

  }

  public String getId()
  {
    return id;
  }

  public void setId(String id)
  {
    this.id = id;
  }

  public String getName()
  {
    return name;
  }

  public void setName(String name)
  {
    this.name = name;
  }

}

CollectorPluginData.java

package com.test;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;

import java.util.ArrayList;
import java.util.List;

public class CollectorPluginData
{
  private String pluginName;
  private String timeStamp;
  private String hostName;
  private String serialNumber;
  private String model;
  private List<Component> componentList;

  public String getSerialNumber()
  {
    return serialNumber;
  }

  public void setSerialNumber(String serialNumber)
  {
    this.serialNumber = serialNumber;
  }

  public String getModel()
  {
    return model;
  }

  public void setModel(String model)
  {
    this.model = model;
  }

  public String getHostName()
  {
    return hostName;
  }

  public void setHostName(String hostName)
  {
    this.hostName = hostName;
  }

  public String getPluginName()
  {
    return pluginName;
  }

  public void setPluginName(String pluginName)
  {
    this.pluginName = pluginName;
  }

  public String getTimeStamp()
  {
    return timeStamp;
  }

  public void setTimeStamp(String timeStamp)
  {
    this.timeStamp = timeStamp;
  }

  public List<Component> getComponentList()
  {
    return componentList;
  }

  public void setComponentList(List<Component> componentList)
  {
    this.componentList = componentList;
  }

  public void addComponent(Component component)
  {
    if (componentList == null)
    {
      componentList = new ArrayList<Component>();
    }
    componentList.add(component);
  }
}

1 个答案:

答案 0 :(得分:1)

这确实是一个错误。 问题在于使用“包含”:Drools(MVEL)非常自由 假设properties contains "X"应解释为properties.containsKey("X")。 但是,在一些迭代之后,约束的即时编译强制执行更严格的模式,其中前一个表达式无法正确计算。 我们将讨论最佳解决方案。无论如何,我建议使用properties.containsKey ...或者甚至删除包含检查,因为当密钥不存在时,map访问器将只返回null。