2017-07-10 65 views
4

我正在嘗試在drools中實現序列化。我的問題是,之前,之前......流水線融合運營商未按預期序列化。時序運算符在Drools 6.5.0和Drools 7.0.0序列化後失敗

如果我不使用序列化和反序列化,我的規則正常工作。

我附加了一個複製器。誰能告訴我問題是什麼。我希望規則只能射擊一次。它應該在03:06:00發射一次,但是它會在3:04:00發射3次,在3:06:00發射2次。

事件是連載:

package com.reproducer; 

import java.io.Serializable; 
import java.util.Date; 

import org.apache.commons.lang3.builder.ToStringBuilder; 

public class EventA implements Serializable { 

/** 
* 
*/ 
private static final long serialVersionUID = 8129243856721618942L; 
private int value; 
private Date timestamp; 

public EventA(Date timestamp, int value) { 
    this.value = value; 
    this.timestamp = timestamp; 
} 

public Date getTimestamp() { 
    return timestamp; 
} 

public int getValue() { 
    return value; 
} 

@Override 
public String toString() { 
     return new ToStringBuilder(this) 
       .append("value", this.value) 
       .append("timestamp", this.getTimestamp()).toString(); 
    } 
} 

測試:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(loader = AnnotationConfigContextLoader.class) 
public class Reproducer { 
    // date formatter for simulation data and tests 
    private static DateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 

    @Configuration 
    static class ContextConfiguration { 

    } 

    private KieBase kieBase; 
    private static KieSession ksession; 
    private static SessionPseudoClock clock; 
    private KieSessionConfiguration sessionConfig; 

    public byte[] serializedSession; 

    @Test 
    public void ruleTest() { 
     List<EventA> events = getSimulationEvents(); 
     startKnowledgeSession(events.get(0).getTimestamp(), false); 
     runSimulation(events); 
    } 

    private static Date parseDate(String input) { 
     Date d = null; 
     try { 
      d = dateFormatter.parse(input); 
     } catch (ParseException e) { 
      e.printStackTrace(); 
     } 
     return d; 
    } 

    private void runSimulation(List<EventA> events) { 

     for (EventA current : events) { 

      KieSession ksession2 = kieBase.newKieSession(sessionConfig, null); 

      Marshaller marshaller = KieServices.Factory.get().getMarshallers().newMarshaller(kieBase); 

      try { 
       ByteArrayInputStream bais = new ByteArrayInputStream(serializedSession); 
       ksession2 = marshaller.unmarshall(bais, sessionConfig, null); 
       clock = ksession2.getSessionClock(); 
       bais.close(); 
      } catch (ClassNotFoundException e) { 
       e.printStackTrace(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 

      long currTime = clock.getCurrentTime(); 
      long nextTime = current.getTimestamp().getTime(); 

      while (currTime <= (nextTime - 1000)) { 
       clock.advanceTime(1000, TimeUnit.MILLISECONDS); 
       ksession2.fireAllRules(); 
       currTime += 1000; 
      } 

      long diff = nextTime - currTime; 
      if (diff > 0) { 
       clock.advanceTime(diff, TimeUnit.MILLISECONDS); 
      } 

      ksession2.insert(current); 
      ksession2.fireAllRules(); 

      // serialize knowledge session 
      try { 
       final ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
       marshaller.marshall(baos, ksession2); 
       serializedSession = baos.toByteArray(); 
      } catch (IOException e2) { 
       e2.printStackTrace(); 
      } 
      ksession2.halt(); 
      ksession2.dispose(); 
     } 
    } 

    private List<EventA> getSimulationEvents() { 
     List<EventA> events = new ArrayList<EventA>(); 

     events.add(new EventA(parseDate("2010-01-01 02:00:00"), 0)); 
     events.add(new EventA(parseDate("2010-01-01 03:00:00"), 1)); 
     events.add(new EventA(parseDate("2010-01-01 03:01:00"), 0)); 
     events.add(new EventA(parseDate("2010-01-01 03:02:00"), 1)); 
     events.add(new EventA(parseDate("2010-01-01 03:03:00"), 0)); 
     events.add(new EventA(parseDate("2010-01-01 03:04:00"), 0)); 
     events.add(new EventA(parseDate("2010-01-01 03:05:00"), 0)); 
     events.add(new EventA(parseDate("2010-01-01 03:06:00"), 0)); 
     events.add(new EventA(parseDate("2010-01-01 03:07:00"), 0)); 

     return events; 
    } 

    private void startKnowledgeSession(Date startTime, boolean onHolidays) { 
     // create configuration 

     StringBuffer drlR1 = new StringBuffer(); 
     drlR1.append("package test\n"); 
     drlR1.append("dialect \"mvel\"\n"); 
     drlR1.append("import com.reproducer.EventA\n"); 
     drlR1.append("import java.util.Date\n"); 
     drlR1.append("declare EventA\n"); 
     drlR1.append(" @role(event)\n"); 
     drlR1.append(" @timestamp(timestamp)\n"); 
     drlR1.append("end\n"); 
     drlR1.append("rule test\n"); 
     drlR1.append(" when\n"); 
     drlR1.append("  $event : EventA(getValue() == 1)\n"); 
     drlR1.append(" not(EventA(getValue() == 1, this after [1ms,4m] $event))\n"); 
     drlR1.append(" then\n"); 
     drlR1.append(
       "  System.out.println(\"Fired \"+ new Date(drools.getWorkingMemory().getSessionClock().getCurrentTime()));\n"); 
     drlR1.append("end\n"); 

     kieBase = new KieHelper().addContent(drlR1.toString(), ResourceType.DRL).build(EventProcessingOption.STREAM); 

     sessionConfig = KnowledgeBaseFactory.newKnowledgeSessionConfiguration(); 
     sessionConfig.setOption(ClockTypeOption.get(ClockType.PSEUDO_CLOCK.getId())); 
     sessionConfig.setOption(TimedRuleExecutionOption.YES); 
     sessionConfig.setOption(TimerJobFactoryOption.get("trackable")); 
     sessionConfig.setOption(ClockTypeOption.get("pseudo")); 

     ksession = kieBase.newKieSession(sessionConfig, null); 

     // set clock reference 
     clock = ksession.getSessionClock(); 
     clock.advanceTime(startTime.getTime(), TimeUnit.MILLISECONDS); 

     sessionConfig = ksession.getSessionConfiguration(); 
     // serialize knowledge session 
     try { 
      Marshaller marshaller = KieServices.Factory.get().getMarshallers().newMarshaller(kieBase); 
      ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
      marshaller.marshall(baos, ksession); 

      serializedSession = baos.toByteArray(); 
     } catch (IOException e2) { 
      e2.printStackTrace(); 
     } 
    } 
} 

回答

0

我在JBoss的開發吉拉Bug Report這個問題開了一個bug報告。這是drools核心引擎中的一個bug。它將在版本7.2.0Final中修復。