AnsweredAssumed Answered

Use history service to track/audit variable updates?

Question asked by sistar on Jan 23, 2012
As allready discussed in http://forums.activiti.org/en/viewtopic.php?f=6&t=2250&hilit=+revision the revision number of a variable is not increased when a new value is assigned to an existing variable in a process-instance.
Apparently the only way to increase the revision counter is a user task.
Increasing the revision in using a user task is described in AIA p. 79 (unfortunately without any mention of the described situation for programmatic assignment..):

historic variable update, revision 0, variable type name string, variable name isbn, Variable value '123456'
historic variable update, revision 1, variable type name string, variable name isbn, Variable value '654321'


In an extended test both
<serviceTask id="servicetask2" name="setISBN" activiti:expression="666666" activiti:resultVariableName="isbn"></serviceTask>

and
public class AssignIsbn implements JavaDelegate{
    public void execute(DelegateExecution execution) throws Exception {
        execution.setVariable("isbn","777777");
    }
}

will not increase the revision counter.

historic variable update, revision 0, variable type name string, variable name isbn, Variable value '123456'
historic variable update, revision 1, variable type name string, variable name isbn, Variable value '654321'
historic variable update, revision 0, variable type name string, variable name extraInfo, Variable value 'Extra information'
historic variable update, revision 1, variable type name string, variable name isbn, Variable value '666666'

Is this behaviour intended?

Does this mean, i cannot  track programmatic modifications of process variables, because the revision counter is not updated and
the timestamp's resolution is not sufficent to bring the historic variable updates into the correct order?
Or is there any way to update a process variable programmatically in a JavaDelagate?

If the situation is as described above, what are recommended workarounds/solutions for unambiguous variable auditing in Activiti ?

Best regards
Ralf

P.S. Use the attached patch to http://activitiinaction.googlecode.com/svn/trunk/bpmn-examples
in order to see the described behaviour, when you start:
bpmn-examples> mvn clean test -Dtest=HistoryServiceTest

P.P.S:
as no file attachments are allowed in this forum:
Index: src/main/resources/chapter4/bookorder.bpmn20.xml
===================================================================
— src/main/resources/chapter4/bookorder.bpmn20.xml   (revision 221)
+++ src/main/resources/chapter4/bookorder.bpmn20.xml   (working copy)
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
-      targetNamespace="http://www.bpmnwithactiviti.org">
+      targetNamespace="http://www.bpmnwithactiviti.org" xmlns:activiti="http://activiti.org/bpmn">
      
   <process id="bookorder" name="bookorder">
      <startEvent id="startevent1" name="Start"/>
@@ -20,6 +20,9 @@
      </userTask>
      <sequenceFlow id="sequenceflow2" name="Sending to management" sourceRef="scripttask1" targetRef="usertask1"/>
      <endEvent id="endevent1" name="End"/>
-      <sequenceFlow id="sequenceflow3" name="flow" sourceRef="usertask1" targetRef="endevent1"/>
+      <sequenceFlow id="sequenceflow3" name="flow" sourceRef="usertask1" targetRef="servicetask2"/>
+      <serviceTask id="servicetask2" name="setISBN" activiti:expression="666666" activiti:resultVariableName="isbn"></serviceTask>
+      <sequenceFlow id="sequenceflow4" name="flow" sourceRef="servicetask2" targetRef="endevent1"/>
+
   </process>
</definitions>
\ No newline at end of file
Index: src/test/java/org/bpmnwithactiviti/chapter4/api/HistoryServiceTest.java
===================================================================
— src/test/java/org/bpmnwithactiviti/chapter4/api/HistoryServiceTest.java   (revision 221)
+++ src/test/java/org/bpmnwithactiviti/chapter4/api/HistoryServiceTest.java   (working copy)
@@ -65,7 +65,7 @@
      startAndComplete();
      HistoryService historyService = activitiRule.getHistoryService();
      List<HistoricActivityInstance> activityList = historyService.createHistoricActivityInstanceQuery().list();
-      assertEquals(3, activityList.size());
+      assertEquals(4, activityList.size());
      for (HistoricActivityInstance historicActivityInstance : activityList) {
         assertNotNull(historicActivityInstance.getActivityId());
         System.out.println("history activity " + historicActivityInstance.getActivityName() +
@@ -83,7 +83,7 @@
      HistoryService historyService = activitiRule.getHistoryService();
      List<HistoricDetail> historicVariableUpdateList = historyService.createHistoricDetailQuery().variableUpdates().list();
      assertNotNull(historicVariableUpdateList);
-      assertEquals(3, historicVariableUpdateList.size());
+      assertEquals(4, historicVariableUpdateList.size());
      for (HistoricDetail historicDetail : historicVariableUpdateList) {
         assertTrue(historicDetail instanceof HistoricVariableUpdate);
         HistoricVariableUpdate historicVariableUpdate = (HistoricVariableUpdate) historicDetail;

Outcomes