2017-07-10 4 views
4

J'essaie d'implémenter la sérialisation dans les baves. Mon problème est que les opérateurs de fusion de drools après, avant, ... ne sont pas sérialisés comme prévu.L'opérateur temporel échoue après la sérialisation dans Drools 6.5.0 et Drools 7.0.0

Mes règles fonctionnent correctement si je n'utilise pas la sérialisation et la désérialisation.

J'ai joint un reproducteur. Est-ce que quelqu'un peut me dire quel est le problème. Je m'attends à ce que la règle ne tire qu'une fois. Il devrait tirer une fois à 03:06:00 mais il tire 3 fois, une fois à 3:04:00 et 2 fois à 3:06:00.

événement qui est sérialisé:

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

Test:

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

Répondre

0

j'ai ouvert un rapport de bogue pour ce problème au développeur Jira Bug Report JBOSS. C'était un bug dans le moteur de base de drools. Il sera corrigé avec la version 7.2.0Final.