Start a timer which generates a User Task at a certain time.

2,127 views
Skip to first unread message

Emerald Hieu

unread,
Nov 25, 2014, 4:40:23 AM11/25/14
to camunda-...@googlegroups.com
Hi gurus, 

I'd like to start a timer which generates a User Task at a certain time. How could I do it? I think I should create a timer and set the date for it on the fly (using ExecutionListener), then start it. But how to generate an User Task when the specified time is reached?


Regards,
Emerald Hieu

Emerald Hieu

unread,
Nov 25, 2014, 4:47:25 AM11/25/14
to camunda-...@googlegroups.com
Update: could the "date" of timer be set dynamically?
Camunda 7.1 Final.

webcyberrob

unread,
Nov 25, 2014, 5:03:40 AM11/25/14
to camunda-...@googlegroups.com
Hi Emerald,

Perhaps you want to use an intermediate timer event. Refer to:


You can use an expression to set the timer dynamically.

regards

Rob

Emerald Hieu

unread,
Nov 27, 2014, 12:14:49 AM11/27/14
to camunda-...@googlegroups.com

Hi, 

I have another approach for this post. I create 2 process "A" & "B". Process A generates process B after a period of time using Timer Event.

"Check contracts" creates the below process to remind employee. (see the picture)

1) I tried to set "cycle" dynamically:

${timerEvent.getCycle()}

@Named
public class TimerEvent {
public String getCycle() {
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
calendar.add(Calendar.SECOND, 10);
Date startTime = calendar.getTime();
return iso8601(startTime);
}
private String iso8601(Date date) {
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
String dateStr = dateFormat.format(date);
System.out.println("Date: " + dateStr);
return dateStr;
}
}


but it shows errors:

11:42:59,963 SEVERE [org.camunda.bpm.engine.impl.interceptor.CommandContext] (ServerService Thread Pool -- 90) Error while closing command context: org.camunda.bpm.engine.ProcessEngineException: Unknown property used in expression: ${timerEvent.getCycle()}. Cause: Cannot resolve identifier 'timerEvent'
at org.camunda.bpm.engine.impl.el.JuelExpression.getValue(JuelExpression.java:55)
at org.camunda.bpm.engine.impl.jobexecutor.TimerDeclarationImpl.newJobInstance(TimerDeclarationImpl.java:93)
at org.camunda.bpm.engine.impl.jobexecutor.TimerDeclarationImpl.newJobInstance(TimerDeclarationImpl.java:33)
at org.camunda.bpm.engine.impl.jobexecutor.JobDeclaration.createJobInstance(JobDeclaration.java:59)
at org.camunda.bpm.engine.impl.jobexecutor.TimerDeclarationImpl.createTimer(TimerDeclarationImpl.java:163)
at org.camunda.bpm.engine.impl.jobexecutor.TimerDeclarationImpl.createTimerInstance(TimerDeclarationImpl.java:150)
at org.camunda.bpm.engine.impl.bpmn.deployer.BpmnDeployer.addTimerDeclarations(BpmnDeployer.java:295)
at org.camunda.bpm.engine.impl.bpmn.deployer.BpmnDeployer.adjustStartEventSubscriptions(BpmnDeployer.java:252)
at org.camunda.bpm.engine.impl.bpmn.deployer.BpmnDeployer.deploy(BpmnDeployer.java:161)
at org.camunda.bpm.engine.impl.persistence.deploy.DeploymentCache.deploy(DeploymentCache.java:50)
at org.camunda.bpm.engine.impl.persistence.entity.DeploymentManager.insertDeployment(DeploymentManager.java:42)
at org.camunda.bpm.engine.impl.cmd.DeployCmd.execute(DeployCmd.java:81)
at org.camunda.bpm.engine.impl.cmd.DeployCmd.execute(DeployCmd.java:50)
at org.camunda.bpm.engine.impl.interceptor.CommandExecutorImpl.execute(CommandExecutorImpl.java:24)
at org.camunda.bpm.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:90)
at org.camunda.bpm.engine.impl.interceptor.JtaTransactionInterceptor.execute(JtaTransactionInterceptor.java:59)
at org.camunda.bpm.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:32)
at org.camunda.bpm.engine.impl.RepositoryServiceImpl.deploy(RepositoryServiceImpl.java:53)
at org.camunda.bpm.engine.impl.repository.DeploymentBuilderImpl.deploy(DeploymentBuilderImpl.java:126)
at org.camunda.bpm.engine.impl.repository.ProcessApplicationDeploymentBuilderImpl.deploy(ProcessApplicationDeploymentBuilderImpl.java:50)
at org.camunda.bpm.container.impl.jboss.service.ProcessApplicationDeploymentService.performDeployment(ProcessApplicationDeploymentService.java:159)
at org.camunda.bpm.container.impl.jboss.service.ProcessApplicationDeploymentService$1.run(ProcessApplicationDeploymentService.java:82)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) [rt.jar:1.7.0]
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334) [rt.jar:1.7.0]
at java.util.concurrent.FutureTask.run(FutureTask.java:166) [rt.jar:1.7.0]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) [rt.jar:1.7.0]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) [rt.jar:1.7.0]
at java.lang.Thread.run(Thread.java:722) [rt.jar:1.7.0]
at org.jboss.threads.JBossThread.run(JBossThread.java:122) [jboss-threads-2.1.0.Final.jar:2.1.0.Final]
Caused by: org.camunda.bpm.engine.impl.javax.el.PropertyNotFoundException: Cannot resolve identifier 'timerEvent'
at org.camunda.bpm.engine.impl.juel.AstIdentifier.eval(AstIdentifier.java:83)
at org.camunda.bpm.engine.impl.juel.AstMethod.invoke(AstMethod.java:79)
at org.camunda.bpm.engine.impl.juel.AstMethod.eval(AstMethod.java:75)
at org.camunda.bpm.engine.impl.juel.AstEval.eval(AstEval.java:50)
at org.camunda.bpm.engine.impl.juel.AstNode.getValue(AstNode.java:26)
at org.camunda.bpm.engine.impl.juel.TreeValueExpression.getValue(TreeValueExpression.java:114)
at org.camunda.bpm.engine.impl.delegate.ExpressionGetInvocation.invoke(ExpressionGetInvocation.java:33)
at org.camunda.bpm.engine.impl.delegate.DelegateInvocation.proceed(DelegateInvocation.java:39)
at org.camunda.bpm.engine.impl.delegate.DefaultDelegateInterceptor.handleInvocation(DefaultDelegateInterceptor.java:42)
at org.camunda.bpm.engine.impl.el.JuelExpression.getValue(JuelExpression.java:50)
... 28 more


2) This code creates process instance of process B.

public class SendTask implements JavaDelegate {
@Inject
private RuntimeService runtimeService;
@Override
public void execute(DelegateExecution execution) throws Exception {
System.out.println("SendTask::execute");
runtimeService.correlateMessage("something");
runtimeService.startProcessInstanceByMessage("something");
}
}


But how does process B catch the message "something" and create the process instance? I'm so confused here. I wonder if there is a sample code of this.


Process A

Process B


Thanks,

Emerald Hieu

thorben....@camunda.com

unread,
Nov 27, 2014, 4:45:08 AM11/27/14
to camunda-...@googlegroups.com
Hi Emerald,

As for the first issue: do you have the engine-cdi module in the classpath of your process application?

Regarding your confusion about how a process can be started by a message:

In your delegate, the lines


runtimeService.correlateMessage("something");
runtimeService.startProcessInstanceByMessage("something");

both express that a process should be started by a message, so you should remove one of them. Note that the first would also trigger intermediate message events if there exists one with that name, so you might go with startProcessInstanceByMessage in this case.

In order to have process B instantiated by the message "something", make sure that process B has a message start event that is triggered by the message "something". You may have a look at the BPMN reference [1] for how to do this.

I also created a simple example for your case, see [2].

I hope that clarifies things for you.

Cheers,
Thorben

[1] http://docs.camunda.org/latest/api-references/bpmn20/#events-message-events-message-start-event
[2] https://github.com/camunda/camunda-bpm-examples/tree/master/startevent/message-start

Emerald Hieu

unread,
Nov 30, 2014, 2:53:24 PM11/30/14
to camunda-...@googlegroups.com
Hi thorben,

1) I'm sure camunda-engine-cdi has been included. This is my full pom.xml:


  <modelVersion>4.0.0</modelVersion>
  <groupId>CamundaStudy</groupId>
  <artifactId>CamundaStudy</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  
<dependencies>
<!-- camunda engine dependency -->
<dependency>
 <groupId>org.camunda.bpm</groupId>
 <artifactId>camunda-engine</artifactId>
 <version>7.1.0-Final</version>
 <scope>provided</scope>
</dependency>
<!-- camunda cdi beans -->
<dependency>
 <groupId>org.camunda.bpm</groupId>
 <artifactId>camunda-engine-cdi</artifactId>
 <version>7.1.0-Final</version>
</dependency>
<!-- provides a default EjbProcessApplication -->
<dependency>
 <groupId>org.camunda.bpm.javaee</groupId>
 <artifactId>camunda-ejb-client</artifactId>
 <version>7.1.0-Final</version>
</dependency>
<!-- Java EE 6 Specification -->
 <dependency>
   <groupId>org.jboss.spec</groupId>
   <artifactId>jboss-javaee-web-6.0</artifactId>
   <version>3.0.2.Final</version>
   <type>pom</type>
   <scope>provided</scope>
   <exclusions>
     <exclusion>
       <artifactId>xalan</artifactId>
       <groupId>xalan</groupId>
     </exclusion>
   </exclusions>
 </dependency>
</dependencies>
  
  
  <build>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.1</version>
        <configuration>
          <source>1.6</source>
          <target>1.6</target>
        </configuration>
      </plugin>
      <plugin>
        <artifactId>maven-war-plugin</artifactId>
        <version>2.3</version>
        <configuration>
          <failOnMissingWebXml>false</failOnMissingWebXml>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>


This is scheduler.bpmn (process A):


<?xml version="1.0" encoding="UTF-8"?>
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:camunda="http://activiti.org/bpmn" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd" id="_ll_rQHjAEeSHd-SsepFFYQ" exporter="camunda modeler" exporterVersion="2.6.0" targetNamespace="http://activiti.org/bpmn">
  <bpmn2:process id="schedulerProcess" isExecutable="true">
    <bpmn2:startEvent id="StartEvent_1" name="Start">
      <bpmn2:outgoing>SequenceFlow_1</bpmn2:outgoing>
      <bpmn2:timerEventDefinition id="TimerEventDefinition_1">
        <bpmn2:timeCycle xsi:type="bpmn2:tFormalExpression">${timerEvent.getCycle()}</bpmn2:timeCycle>
      </bpmn2:timerEventDefinition>
    </bpmn2:startEvent>
    <bpmn2:endEvent id="EndEvent_1" name="End">
      <bpmn2:incoming>SequenceFlow_2</bpmn2:incoming>
    </bpmn2:endEvent>
    <bpmn2:serviceTask id="scheduler" camunda:delegateExpression="${schedulerServiceTask}" name="Scheduler">
      <bpmn2:incoming>SequenceFlow_1</bpmn2:incoming>
      <bpmn2:outgoing>SequenceFlow_2</bpmn2:outgoing>
    </bpmn2:serviceTask>
    <bpmn2:sequenceFlow id="SequenceFlow_1" name="" sourceRef="StartEvent_1" targetRef="scheduler"/>
    <bpmn2:sequenceFlow id="SequenceFlow_2" name="" sourceRef="scheduler" targetRef="EndEvent_1"/>
  </bpmn2:process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="schedulerProcess">
      <bpmndi:BPMNShape id="_BPMNShape_StartEvent_12" bpmnElement="StartEvent_1">
        <dc:Bounds height="36.0" width="36.0" x="132.0" y="119.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="_BPMNShape_EndEvent_16" bpmnElement="EndEvent_1">
        <dc:Bounds height="36.0" width="36.0" x="456.0" y="119.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="0.0" width="0.0" x="474.0" y="160.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="_BPMNShape_ServiceTask_8" bpmnElement="scheduler">
        <dc:Bounds height="80.0" width="100.0" x="264.0" y="97.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_1" bpmnElement="SequenceFlow_1" sourceElement="_BPMNShape_StartEvent_12" targetElement="_BPMNShape_ServiceTask_8">
        <di:waypoint xsi:type="dc:Point" x="168.0" y="137.0"/>
        <di:waypoint xsi:type="dc:Point" x="264.0" y="137.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_2" bpmnElement="SequenceFlow_2" sourceElement="_BPMNShape_ServiceTask_8" targetElement="_BPMNShape_EndEvent_16">
        <di:waypoint xsi:type="dc:Point" x="364.0" y="137.0"/>
        <di:waypoint xsi:type="dc:Point" x="456.0" y="137.0"/>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn2:definitions>


This is reminder.bpmn (process B):


<?xml version="1.0" encoding="UTF-8"?>
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:camunda="http://activiti.org/bpmn" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd" id="_qRw20HjAEeSHd-SsepFFYQ" exporter="camunda modeler" exporterVersion="2.6.0" targetNamespace="http://activiti.org/bpmn">
  <bpmn2:process id="reminderProcess" isExecutable="true">
    <bpmn2:endEvent id="EndEvent_1" name="End">
      <bpmn2:incoming>SequenceFlow_2</bpmn2:incoming>
    </bpmn2:endEvent>
    <bpmn2:userTask id="reminder" camunda:formKey="app:pages/reminder.jsf" name="Reminder">
      <bpmn2:incoming>SequenceFlow_3</bpmn2:incoming>
      <bpmn2:outgoing>SequenceFlow_2</bpmn2:outgoing>
    </bpmn2:userTask>
    <bpmn2:sequenceFlow id="SequenceFlow_2" name="" sourceRef="reminder" targetRef="EndEvent_1"/>
    <bpmn2:startEvent id="StartEvent_2" name="Start">
      <bpmn2:outgoing>SequenceFlow_3</bpmn2:outgoing>
      <bpmn2:messageEventDefinition id="MessageEventDefinition_1" messageRef="Message_1"/>
    </bpmn2:startEvent>
    <bpmn2:sequenceFlow id="SequenceFlow_3" name="" sourceRef="StartEvent_2" targetRef="reminder"/>
  </bpmn2:process>
  <bpmn2:message id="Message_1" name="remind"/>
  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="reminderProcess">
      <bpmndi:BPMNShape id="_BPMNShape_EndEvent_17" bpmnElement="EndEvent_1">
        <dc:Bounds height="36.0" width="36.0" x="443.0" y="107.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="0.0" width="0.0" x="461.0" y="148.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="_BPMNShape_UserTask_5" bpmnElement="reminder">
        <dc:Bounds height="80.0" width="100.0" x="263.0" y="87.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_2" bpmnElement="SequenceFlow_2" sourceElement="_BPMNShape_UserTask_5" targetElement="_BPMNShape_EndEvent_17">
        <di:waypoint xsi:type="dc:Point" x="363.0" y="127.0"/>
        <di:waypoint xsi:type="dc:Point" x="403.0" y="127.0"/>
        <di:waypoint xsi:type="dc:Point" x="403.0" y="125.0"/>
        <di:waypoint xsi:type="dc:Point" x="443.0" y="125.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="_BPMNShape_StartEvent_14" bpmnElement="StartEvent_2">
        <dc:Bounds height="36.0" width="36.0" x="125.0" y="107.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="0.0" width="0.0" x="143.0" y="148.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_3" bpmnElement="SequenceFlow_3" sourceElement="_BPMNShape_StartEvent_14" targetElement="_BPMNShape_UserTask_5">
        <di:waypoint xsi:type="dc:Point" x="161.0" y="125.0"/>
        <di:waypoint xsi:type="dc:Point" x="212.0" y="125.0"/>
        <di:waypoint xsi:type="dc:Point" x="212.0" y="127.0"/>
        <di:waypoint xsi:type="dc:Point" x="263.0" y="127.0"/>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn2:definitions>


It generates the same error: Unknown property used in expression: ${timerEvent.getCycle()}. Cause: Cannot resolve identifier 'timerEvent'

I suspect that EL isn't supported for Timer Definition.

2) startProcessInstanceByMessage() works now with message event. Thank you.

Regards,
Emerald Hieu

thorben....@camunda.com

unread,
Dec 1, 2014, 12:02:50 PM12/1/14
to camunda-...@googlegroups.com
Hi Emerald,

In general, EL is supported for timer declarations. During process application deployment, the duration cannot be resolved from a CDI bean since the engine is not yet aware that it has to look up the bean from the deployed process application. I created a bug ticket [1] for that. This only applies to a shared engine setting. With an embedded engine, you should also be able to use CDI beans for timer start events.

Also, you should be able to use CDI beans for the creation of intermediate timers in both, shared and embedded case.

Best regards,
Thorben

[1] https://app.camunda.com/jira/browse/CAM-3163
Reply all
Reply to author
Forward
0 new messages