@Override public Object execute(Context context) { KieSession kieSession = ((KnowledgeCommandContext) context).getKieSession(); TimerManager tm = getTimerManager(kieSession); RuleFlowProcessInstance wfp = (RuleFlowProcessInstance) kieSession.getProcessInstance(processInstanceId); for (NodeInstance nodeInstance : wfp.getNodeInstances()) { if (nodeInstance instanceof TimerNodeInstance) { TimerNodeInstance tni = (TimerNodeInstance) nodeInstance; if (tni.getNodeName().equals(timerName)) { TimerInstance timer = tm.getTimerMap().get(tni.getTimerId()); tm.cancelTimer(timer.getTimerId()); TimerInstance newTimer = new TimerInstance(); if (delay != 0) { long diff = System.currentTimeMillis() - timer.getActivated().getTime(); newTimer.setDelay(delay * 1000 - diff); } newTimer.setPeriod(period); newTimer.setRepeatLimit(repeatLimit); newTimer.setTimerId(timer.getTimerId()); tm.registerTimer(newTimer, wfp); tni.internalSetTimerId(newTimer.getId()); break; } } } return null; }
public void internalTrigger(NodeInstance from, String type) { super.internalTrigger(from, type); // activate timers Map<Timer, DroolsAction> timers = getEventBasedNode().getTimers(); if (timers != null) { addTimerListener(); timerInstances = new ArrayList<Long>(timers.size()); TimerManager timerManager = ((InternalProcessRuntime) getProcessInstance().getKnowledgeRuntime().getProcessRuntime()) .getTimerManager(); for (Timer timer : timers.keySet()) { TimerInstance timerInstance = createTimerInstance(timer); timerManager.registerTimer(timerInstance, (ProcessInstance) getProcessInstance()); timerInstances.add(timerInstance.getId()); } } if (getEventBasedNode().getBoundaryEvents() != null) { for (String name : getEventBasedNode().getBoundaryEvents()) { boolean isActive = ((InternalAgenda) getProcessInstance().getKnowledgeRuntime().getAgenda()) .isRuleActiveInRuleFlowGroup("DROOLS_SYSTEM", name, getProcessInstance().getId()); if (isActive) { getProcessInstance().getKnowledgeRuntime().signalEvent(name, null); } else { addActivationListener(); } } } }
public void signalEvent(String type, Object event) { if ("timerTriggered".equals(type)) { TimerInstance timerInstance = (TimerInstance) event; if (timerInstances.contains(timerInstance.getId())) { triggerTimer(timerInstance); } } else if (type.equals(getActivationType())) { if (event instanceof MatchCreatedEvent) { String name = ((MatchCreatedEvent) event).getMatch().getRule().getName(); if (checkProcessInstance((Activation) ((MatchCreatedEvent) event).getMatch())) { ((MatchCreatedEvent) event).getKieRuntime().signalEvent(name, null); } } } }
private void triggerTimer(TimerInstance timerInstance) { for (Map.Entry<Timer, DroolsAction> entry : getEventBasedNode().getTimers().entrySet()) { if (entry.getKey().getId() == timerInstance.getTimerId()) { executeAction((Action) entry.getValue().getMetaData("Action")); return; } } }
protected TimerInstance createTimerInstance(Timer timer) { TimerInstance timerInstance = new TimerInstance(); KnowledgeRuntime kruntime = getProcessInstance().getKnowledgeRuntime(); if (kruntime != null && kruntime.getEnvironment().get("jbpm.business.calendar") != null) { BusinessCalendar businessCalendar = (BusinessCalendar) kruntime.getEnvironment().get("jbpm.business.calendar"); String delay = resolveVariable(timer.getDelay()); timerInstance.setDelay(businessCalendar.calculateBusinessTimeAsDuration(delay)); if (timer.getPeriod() == null) { timerInstance.setPeriod(0); } else { String period = resolveVariable(timer.getPeriod()); timerInstance.setPeriod(businessCalendar.calculateBusinessTimeAsDuration(period)); } } else { configureTimerInstance(timer, timerInstance); } timerInstance.setTimerId(timer.getId()); return timerInstance; }
protected void configureTimerInstance(Timer timer, TimerInstance timerInstance) { String s = null; long duration = -1; switch (timer.getTimeType()) { case Timer.TIME_CYCLE: if (timer.getPeriod() != null) { timerInstance.setDelay(resolveValue(timer.getDelay())); if (timer.getPeriod() == null) { timerInstance.setPeriod(0); } else { timerInstance.setPeriod(resolveValue(timer.getPeriod())); } } else { if (CronExpression.isValidExpression(timer.getDelay())) { timerInstance.setCronExpression(timer.getDelay()); } else { // when using ISO date/time period is not set long[] repeatValues = null; try { repeatValues = DateTimeUtils.parseRepeatableDateTime(timer.getDelay()); } catch (RuntimeException e) { // cannot parse delay, trying to interpret it s = resolveVariable(timer.getDelay()); repeatValues = DateTimeUtils.parseRepeatableDateTime(s); } if (repeatValues.length == 3) { int parsedReapedCount = (int) repeatValues[0]; if (parsedReapedCount > -1) { timerInstance.setRepeatLimit(parsedReapedCount + 1); } timerInstance.setDelay(repeatValues[1]); timerInstance.setPeriod(repeatValues[2]); } else if (repeatValues.length == 2) { timerInstance.setDelay(repeatValues[0]); timerInstance.setPeriod(repeatValues[1]); } else { timerInstance.setDelay(repeatValues[0]); timerInstance.setPeriod(0); } } } break; case Timer.TIME_DURATION: try { duration = DateTimeUtils.parseDuration(timer.getDelay()); } catch (RuntimeException e) { // cannot parse delay, trying to interpret it s = resolveVariable(timer.getDelay()); duration = DateTimeUtils.parseDuration(s); } timerInstance.setDelay(duration); timerInstance.setPeriod(0); break; case Timer.TIME_DATE: try { duration = DateTimeUtils.parseDateAsDuration(timer.getDate()); } catch (RuntimeException e) { // cannot parse delay, trying to interpret it s = resolveVariable(timer.getDate()); duration = DateTimeUtils.parseDateAsDuration(s); } timerInstance.setDelay(duration); timerInstance.setPeriod(0); break; default: break; } }
protected TimerInstance createTimerInstance(Timer timer) { TimerInstance timerInstance = new TimerInstance(); KnowledgeRuntime kruntime = getProcessInstance().getKnowledgeRuntime(); if (kruntime != null && kruntime.getEnvironment().get("jbpm.business.calendar") != null) { BusinessCalendar businessCalendar = (BusinessCalendar) kruntime.getEnvironment().get("jbpm.business.calendar"); String delay = null; switch (timer.getTimeType()) { case Timer.TIME_CYCLE: if (CronExpression.isValidExpression(timer.getDelay())) { timerInstance.setCronExpression(timer.getDelay()); } else { String tempDelay = resolveVariable(timer.getDelay()); String tempPeriod = resolveVariable(timer.getPeriod()); if (DateTimeUtils.isRepeatable(tempDelay)) { String[] values = DateTimeUtils.parseISORepeatable(tempDelay); String tempRepeatLimit = values[0]; tempDelay = values[1]; tempPeriod = values[2]; if (!tempRepeatLimit.isEmpty()) { try { int repeatLimit = Integer.parseInt(tempRepeatLimit); if (repeatLimit > -1) { timerInstance.setRepeatLimit(repeatLimit + 1); } } catch (NumberFormatException e) { // ignore } } } timerInstance.setDelay(businessCalendar.calculateBusinessTimeAsDuration(tempDelay)); if (tempPeriod == null) { timerInstance.setPeriod(0); } else { timerInstance.setPeriod(businessCalendar.calculateBusinessTimeAsDuration(tempPeriod)); } } break; case Timer.TIME_DURATION: delay = resolveVariable(timer.getDelay()); timerInstance.setDelay(businessCalendar.calculateBusinessTimeAsDuration(delay)); timerInstance.setPeriod(0); break; case Timer.TIME_DATE: // even though calendar is available concrete date was provided so it shall be used configureTimerInstance(timer, timerInstance); default: break; } } else { configureTimerInstance(timer, timerInstance); } timerInstance.setTimerId(timer.getId()); return timerInstance; }
@Test @Ignore public void testTimer() { // AbstractRuleBase ruleBase = (AbstractRuleBase) RuleBaseFactory.newRuleBase(); // ExecutorService executorService = new DefaultExecutorService(); // final StatefulSession workingMemory = new ReteooStatefulSession(1, ruleBase, // executorService); // executorService.setCommandExecutor( new CommandExecutor( workingMemory ) ); KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(); final StatefulKnowledgeSession workingMemory = kbase.newStatefulKnowledgeSession(); RuleFlowProcessInstance processInstance = new RuleFlowProcessInstance() { private static final long serialVersionUID = 510l; public void signalEvent(String type, Object event) { if ("timerTriggered".equals(type)) { TimerInstance timer = (TimerInstance) event; logger.info("Timer {} triggered", timer.getId()); counter++; } } }; processInstance.setKnowledgeRuntime( ((InternalWorkingMemory) workingMemory).getKnowledgeRuntime()); processInstance.setId(1234); InternalProcessRuntime processRuntime = ((InternalProcessRuntime) ((InternalWorkingMemory) workingMemory).getProcessRuntime()); processRuntime.getProcessInstanceManager().internalAddProcessInstance(processInstance); new Thread( new Runnable() { public void run() { workingMemory.fireUntilHalt(); } }) .start(); TimerManager timerManager = ((InternalProcessRuntime) ((InternalWorkingMemory) workingMemory).getProcessRuntime()) .getTimerManager(); TimerInstance timer = new TimerInstance(); timerManager.registerTimer(timer, processInstance); try { Thread.sleep(1000); } catch (InterruptedException e) { // do nothing } assertEquals(1, counter); counter = 0; timer = new TimerInstance(); timer.setDelay(500); timerManager.registerTimer(timer, processInstance); assertEquals(0, counter); try { Thread.sleep(1000); } catch (InterruptedException e) { // do nothing } assertEquals(1, counter); counter = 0; timer = new TimerInstance(); timer.setDelay(500); timer.setPeriod(300); timerManager.registerTimer(timer, processInstance); assertEquals(0, counter); try { Thread.sleep(700); } catch (InterruptedException e) { // do nothing } assertEquals(1, counter); try { Thread.sleep(1000); } catch (InterruptedException e) { // do nothing } // we can't know exactly how many times this will fire as timers are not precise, but should be // atleast 4 assertTrue(counter >= 4); timerManager.cancelTimer(timer.getId()); int lastCount = counter; try { Thread.sleep(1000); } catch (InterruptedException e) { // do nothing } assertEquals(lastCount, counter); }