@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;
  }
  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;
  }
Exemple #5
0
  @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);
  }