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