Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(webapps): activityIdIn filter returns all relevant instances #4758

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -402,8 +402,10 @@

<bind name="INC_JOIN" value="false" />
<bind name="HAI_JOIN" value="false" />
<bind name="INCACT_JOIN" value="false" />
<bind name="RU_EXE_JOIN" value="false" />
<bind name="JOIN_TYPE" value="'inner join'" />
<bind name="INCACT_JOIN" value="false" />


<foreach collection="queries" item="query">
<if test="query.isOrQueryActive">
Expand All @@ -414,12 +416,13 @@
<bind name="INC_JOIN" value="true" />
</if>

<if test="query != null &amp;&amp; (query.executedActivityIds != null and query.executedActivityIds.length > 0) || (query.activeActivityIds != null and query.activeActivityIds.length > 0) || (query.activityIds != null and query.activityIds.length > 0)">
<if test="query != null &amp;&amp; (query.executedActivityIds != null and query.executedActivityIds.length > 0) || (query.activeActivityIds != null and query.activeActivityIds.length > 0)">
<bind name="HAI_JOIN" value="true" />
</if>

<if test="query != null &amp;&amp; (query.activityIds != null and query.activityIds.length > 0)">
<bind name="INCACT_JOIN" value="true" />
<bind name="RU_EXE_JOIN" value="true" />
</if>
</foreach>

Expand All @@ -435,6 +438,12 @@
LEFT JOIN ${prefix}ACT_HI_INCIDENT INCACT on SELF.PROC_INST_ID_ = INCACT.PROC_INST_ID_
</if>

<if test="RU_EXE_JOIN">
LEFT JOIN ${prefix}ACT_RU_EXECUTION REXE on SELF.PROC_INST_ID_ = REXE.PROC_INST_ID_
</if>



<!-- actual value conditions are checked in the WHERE part;
however here we must join once for every variable condition.
It is important that in the WHERE part we use the same table
Expand Down Expand Up @@ -645,17 +654,19 @@

<if test="query.activityIds != null and query.activityIds.length > 0">
${queryType} (
(
HAI.END_TIME_ IS NULL
AND HAI.ACT_ID_ IN
(
INCACT.ACTIVITY_ID_ IN
<foreach item="activityId" index="index" collection="query.activityIds" open="(" separator="," close=")">
#{activityId}
</foreach>
) OR INCACT.ACTIVITY_ID_ IN
)
OR (
REXE.ACT_ID_ IN
<foreach item="activityId" index="index" collection="query.activityIds" open="(" separator="," close=")">
#{activityId}
</foreach>
)
)
</if>

<if test="query.executedActivityIds != null and query.executedActivityIds.length > 0">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1657,11 +1657,42 @@ public void testQueryByNonLeafActivityId() {
@Test
@RequiredHistoryLevel(ProcessEngineConfiguration.HISTORY_FULL)
public void testQueryByAsyncBeforeActivityId() {
// For a historic instance when AsyncBefore is used the historic activity is only created when the execution is scheduled
// For process instances that have a token just before a AsyncBefore activity
// In the runtimeInstanceQuery activityIdIn filter returns instances that are not scheduled yet
// In historicInstanceQuery activityIdIn filter does not return instances that are not scheduled yet
// given
ProcessDefinition testProcess = testHelper.deployAndGetDefinition(ProcessModels.newModel()
.startEvent("start").camundaAsyncBefore()
.serviceTask("task").camundaAsyncBefore().camundaExpression("${true}")
.endEvent("end").camundaAsyncBefore()
.done()
);

// when
ProcessInstance instanceBeforeStart = runtimeService.startProcessInstanceById(testProcess.getId());
ProcessInstance instanceBeforeTask = runtimeService.startProcessInstanceById(testProcess.getId());
executeJobForProcessInstance(instanceBeforeTask);
ProcessInstance instanceBeforeEnd = runtimeService.startProcessInstanceById(testProcess.getId());
executeJobForProcessInstance(instanceBeforeEnd);
executeJobForProcessInstance(instanceBeforeEnd);

// then
HistoricProcessInstanceQuery historicQuery = historyService.createHistoricProcessInstanceQuery().activityIdIn("start");
assertNotNull(historicQuery.singleResult());
ProcessInstanceQuery runtimeQuery = runtimeService.createProcessInstanceQuery().activityIdIn("start");
assertEquals(instanceBeforeStart.getId(), runtimeQuery.singleResult().getProcessInstanceId());

historicQuery = historyService.createHistoricProcessInstanceQuery().activityIdIn("task");
assertEquals(instanceBeforeTask.getId(), historicQuery.singleResult().getId());
runtimeQuery = runtimeService.createProcessInstanceQuery().activityIdIn("task");
assertEquals(instanceBeforeTask.getId(), runtimeQuery.singleResult().getProcessInstanceId());

historicQuery = historyService.createHistoricProcessInstanceQuery().activityIdIn("end");
assertEquals(instanceBeforeEnd.getId(), historicQuery.singleResult().getId());
runtimeQuery = runtimeService.createProcessInstanceQuery().activityIdIn("end");
assertEquals(instanceBeforeEnd.getId(), runtimeQuery.singleResult().getProcessInstanceId());
}

@Test
@RequiredHistoryLevel(ProcessEngineConfiguration.HISTORY_FULL)
public void testQueryByAsyncBeforeActivityIdWithScope() {
// given
ProcessDefinition testProcess = testHelper.deployAndGetDefinition(ProcessModels.newModel()
.startEvent("start").camundaAsyncBefore()
Expand Down Expand Up @@ -1689,34 +1720,58 @@ public void testQueryByAsyncBeforeActivityId() {

// then
HistoricProcessInstanceQuery historicQuery = historyService.createHistoricProcessInstanceQuery().activityIdIn("start");
assertNull(historicQuery.singleResult());
assertNotNull(historicQuery.singleResult());
ProcessInstanceQuery runtimeQuery = runtimeService.createProcessInstanceQuery().activityIdIn("start");
assertEquals(instanceBeforeStart.getId(), runtimeQuery.singleResult().getProcessInstanceId());

historicQuery = historyService.createHistoricProcessInstanceQuery().activityIdIn("subProcess");
assertReturnedProcessInstances(historicQuery, instanceBeforeTask);
runtimeQuery = runtimeService.createProcessInstanceQuery().activityIdIn("subProcess");
assertEquals(instanceBeforeSubProcess.getId(), runtimeQuery.singleResult().getProcessInstanceId());
assertThat(historicQuery.list().stream().map(HistoricProcessInstance::getId).collect(Collectors.toList()))
.containsExactlyInAnyOrder(instanceBeforeSubProcess.getId());

historicQuery = historyService.createHistoricProcessInstanceQuery().activityIdIn("task");
assertNull(historicQuery.singleResult());
runtimeQuery = runtimeService.createProcessInstanceQuery().activityIdIn("task");
assertEquals(instanceBeforeTask.getId(), runtimeQuery.singleResult().getProcessInstanceId());
assertEquals(instanceBeforeTask.getId(), historicQuery.singleResult().getId());

historicQuery = historyService.createHistoricProcessInstanceQuery().activityIdIn("end");
assertNull(historicQuery.singleResult());
runtimeQuery = runtimeService.createProcessInstanceQuery().activityIdIn("end");
assertEquals(instanceBeforeEnd.getId(), runtimeQuery.singleResult().getProcessInstanceId());
assertEquals(instanceBeforeEnd.getId(), historicQuery.singleResult().getId());
}


@Test
@RequiredHistoryLevel(ProcessEngineConfiguration.HISTORY_FULL)
public void testQueryByAsyncAfterActivityId() {
// For a historic activity the end time is set after it is executed => the activity is not considered active anymore,
// this is not changed if AsyncAfter is used
// if the task is a subprocess end time will only be set after the subprocess is terminated
// For the runtime query the execution is still visible if AsyncAfter is used (I assume we delete the execution when scheduling next activity)
// given
ProcessDefinition testProcess = testHelper.deployAndGetDefinition(ProcessModels.newModel()
.startEvent("start").camundaAsyncAfter()
.serviceTask("task").camundaAsyncAfter().camundaExpression("${true}")
.endEvent("end").camundaAsyncAfter()
.done()
);

// when
ProcessInstance instanceAfterStart = runtimeService.startProcessInstanceById(testProcess.getId());
ProcessInstance instanceAfterTask = runtimeService.startProcessInstanceById(testProcess.getId());
executeJobForProcessInstance(instanceAfterTask);
ProcessInstance instanceAfterEnd = runtimeService.startProcessInstanceById(testProcess.getId());
executeJobForProcessInstance(instanceAfterEnd);
executeJobForProcessInstance(instanceAfterEnd);

// then
HistoricProcessInstanceQuery historicQuery = historyService.createHistoricProcessInstanceQuery().activityIdIn("start");
assertNotNull(historicQuery.singleResult());
assertEquals(instanceAfterStart.getId(), historicQuery.singleResult().getId());

historicQuery = historyService.createHistoricProcessInstanceQuery().activityIdIn("task");
assertNotNull(historicQuery.singleResult());
assertEquals(instanceAfterTask.getId(), historicQuery.singleResult().getId());

historicQuery = historyService.createHistoricProcessInstanceQuery().activityIdIn("end");
assertNotNull(historicQuery.singleResult());
assertEquals(instanceAfterEnd.getId(), historicQuery.singleResult().getId());
}

@Test
@RequiredHistoryLevel(ProcessEngineConfiguration.HISTORY_FULL)
public void testQueryByAsyncAfterActivityIdWithScope() {
// given
ProcessDefinition testProcess = testHelper.deployAndGetDefinition(ProcessModels.newModel()
.startEvent("start").camundaAsyncAfter()
Expand All @@ -1743,24 +1798,18 @@ public void testQueryByAsyncAfterActivityId() {
executeJobForProcessInstance(instanceAfterEnd);

HistoricProcessInstanceQuery historicQuery = historyService.createHistoricProcessInstanceQuery().activityIdIn("start");
assertNull(historicQuery.singleResult());
ProcessInstanceQuery runtimeQuery = runtimeService.createProcessInstanceQuery().activityIdIn("start");
assertEquals(instanceAfterStart.getId(), runtimeQuery.singleResult().getProcessInstanceId());
assertNotNull(historicQuery.singleResult());
assertEquals(instanceAfterStart.getId(), historicQuery.singleResult().getId());

historicQuery = historyService.createHistoricProcessInstanceQuery().activityIdIn("task");
assertNull(historicQuery.singleResult());
runtimeQuery = runtimeService.createProcessInstanceQuery().activityIdIn("task");
assertEquals(instanceAfterTask.getId(), runtimeQuery.singleResult().getProcessInstanceId());
assertEquals(instanceAfterTask.getId(), historicQuery.singleResult().getId());

historicQuery = historyService.createHistoricProcessInstanceQuery().activityIdIn("subProcess");
assertReturnedProcessInstances(historicQuery, instanceAfterTask);
runtimeQuery = runtimeService.createProcessInstanceQuery().activityIdIn("subProcess");
assertEquals(instanceAfterSubProcess.getId(), runtimeQuery.singleResult().getProcessInstanceId());
historicQuery = historyService.createHistoricProcessInstanceQuery().activityIdIn("subProcess"); // 12 (instanceAfterTask), 23
assertThat(historicQuery.list().stream().map(HistoricProcessInstance::getId).collect(Collectors.toList()))
.containsExactlyInAnyOrder(instanceAfterSubProcess.getId());

historicQuery = historyService.createHistoricProcessInstanceQuery().activityIdIn("end");
assertNull(historicQuery.singleResult());
runtimeQuery = runtimeService.createProcessInstanceQuery().activityIdIn("end");
assertEquals(instanceAfterEnd.getId(), runtimeQuery.singleResult().getProcessInstanceId());
assertEquals(instanceAfterEnd.getId(), historicQuery.singleResult().getId());
}

@Test
Expand Down Expand Up @@ -1794,7 +1843,7 @@ public void testQueryByActivityIdDuringCompensation() {

// then
HistoricProcessInstanceQuery historicQuery = historyService.createHistoricProcessInstanceQuery().activityIdIn("subProcess");
assertNull(historicQuery.singleResult());
assertNotNull(historicQuery.singleResult());
ProcessInstanceQuery runtimeQuery = runtimeService.createProcessInstanceQuery().activityIdIn("subProcess");
assertEquals(processInstance.getId(), runtimeQuery.singleResult().getProcessInstanceId());

Expand Down Expand Up @@ -1906,7 +1955,7 @@ public void testHistoricProcInstQueryWithActivityIdsWithFailingActivity() {
runtimeService.startProcessInstanceByKey("failingProcess");
testHelper.executeAvailableJobs();

runtimeService.startProcessInstanceByKey("failingProcess");
ProcessInstance processInstanceInWait = runtimeService.startProcessInstanceByKey("failingProcess");

// assume
assertEquals(2, historyService.createHistoricProcessInstanceQuery().count());
Expand All @@ -1924,8 +1973,9 @@ public void testHistoricProcInstQueryWithActivityIdsWithFailingActivity() {

// then
assertNotNull(result);
assertEquals(1, result.size());
assertEquals(result.get(0).getId(), failingInstance.getId());
assertEquals(2, result.size());
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now the instance that has not failed yet as in async waiting returned correctly.

assertThat(result.stream().map(HistoricProcessInstance::getId).collect(Collectors.toList()))
.containsExactlyInAnyOrder(failingInstance.getId(), processInstanceInWait.getId());
}

@Test
Expand All @@ -1939,7 +1989,7 @@ public void shouldQueryByActivityIdInWithActivityIdOfFailingSubprocess() {

// when
HistoricProcessInstance historicPI =
historyService.createHistoricProcessInstanceQuery().activityIdIn("subProcess").singleResult();
historyService.createHistoricProcessInstanceQuery().activityIdIn("serviceTask").singleResult();

// then
assertThat(historicPI).isNotNull();
Expand Down Expand Up @@ -1977,7 +2027,7 @@ public void shouldQueryByActivityIdInWithActivityIdOfSubprocess() {
taskService.complete(task.getId());
// when
HistoricProcessInstance historicPI =
historyService.createHistoricProcessInstanceQuery().activityIdIn("subProcess").singleResult();
historyService.createHistoricProcessInstanceQuery().activityIdIn("innerTask").singleResult();

// then
assertThat(historicPI).isNotNull();
Expand Down Expand Up @@ -2021,8 +2071,8 @@ public void shouldQueryByActivityIdInWithMultipleScopeAndIncident() {
// when
List<HistoricProcessInstance> queryByInnerServiceActivityId =
historyService.createHistoricProcessInstanceQuery().activityIdIn("innerServiceTask").list();
List<HistoricProcessInstance> queryBySubProcessActivityId =
historyService.createHistoricProcessInstanceQuery().activityIdIn("subProcess").list();
HistoricProcessInstance queryBySubProcessActivityId =
historyService.createHistoricProcessInstanceQuery().activityIdIn("subProcess").singleResult();
List<HistoricProcessInstance> queryByOuterProcessActivityId =
historyService.createHistoricProcessInstanceQuery().activityIdIn("outerTask").list();
List<HistoricProcessInstance> queryByOuterAndInnedActivityId =
Expand All @@ -2032,8 +2082,8 @@ public void shouldQueryByActivityIdInWithMultipleScopeAndIncident() {
assertThat(queryByInnerServiceActivityId.size()).isEqualTo(1);
assertThat(queryByInnerServiceActivityId.get(0).getId()).isEqualTo(processInstance.getId());

assertThat(queryBySubProcessActivityId.size()).isEqualTo(1);
assertThat(queryBySubProcessActivityId.get(0).getId()).isEqualTo(processInstance.getId());
assertNull(queryBySubProcessActivityId);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have 2 instances one at service task innerServiceTask and one in service task outerTask.
Querying by subProcess should return null. The Runtime query has the same behaviour (not returning instances by subProcess activityId)



assertThat(queryByOuterProcessActivityId.size()).isEqualTo(1);
assertThat(queryByOuterProcessActivityId.get(0).getId()).isEqualTo(processInstance2.getId());
Expand All @@ -2060,8 +2110,8 @@ public void shouldQueryByActivityIdInWithMultipleScope() {
// when
List<HistoricProcessInstance> queryByInnerServiceActivityId =
historyService.createHistoricProcessInstanceQuery().activityIdIn("innerTask").list();
List<HistoricProcessInstance> queryBySubProcessActivityId =
historyService.createHistoricProcessInstanceQuery().activityIdIn("subProcess").list();
HistoricProcessInstance queryBySubProcessActivityId =
historyService.createHistoricProcessInstanceQuery().activityIdIn("subProcess").singleResult();
List<HistoricProcessInstance> queryByOuterProcessActivityId =
historyService.createHistoricProcessInstanceQuery().activityIdIn("outerTask").list();
List<HistoricProcessInstance> queryByOuterAndInnedActivityId =
Expand All @@ -2071,8 +2121,7 @@ public void shouldQueryByActivityIdInWithMultipleScope() {
assertThat(queryByInnerServiceActivityId.size()).isEqualTo(1);
assertThat(queryByInnerServiceActivityId.get(0).getId()).isEqualTo(processInstance.getId());

assertThat(queryBySubProcessActivityId.size()).isEqualTo(1);
assertThat(queryBySubProcessActivityId.get(0).getId()).isEqualTo(processInstance.getId());
assertNull(queryBySubProcessActivityId);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have 2 instances one at user task innerTask and one in user task outerTask.
Querying by subProcess should return null. The Runtime query has the same behaviur (not returning instances by subProcess activityId)


assertThat(queryByOuterProcessActivityId.size()).isEqualTo(1);
assertThat(queryByOuterProcessActivityId.get(0).getId()).isEqualTo(processInstance2.getId());
Expand Down
Loading