From da6ee406954c695a3298500663cafe34e5f5c59e Mon Sep 17 00:00:00 2001 From: venetrius Date: Tue, 17 Sep 2024 11:19:50 +0200 Subject: [PATCH 01/11] feature(engine): add activityIdIn filter to HistoricProcessInstanceQuery related to: #4618 --- .../lib/commons/history-process-instance.ftl | 7 +++ .../HistoricProcessInstanceQueryDto.java | 10 ++++ ...icProcessInstanceRestServiceQueryTest.java | 29 ++++++++++ .../history/HistoricProcessInstanceQuery.java | 5 ++ .../HistoricProcessInstanceQueryImpl.java | 13 +++++ .../entity/HistoricProcessInstance.xml | 27 ++++++++- .../history/HistoricProcessInstanceTest.java | 56 +++++++++++++++++++ 7 files changed, 146 insertions(+), 1 deletion(-) diff --git a/engine-rest/engine-rest-openapi/src/main/templates/lib/commons/history-process-instance.ftl b/engine-rest/engine-rest-openapi/src/main/templates/lib/commons/history-process-instance.ftl index 086b3aacceb..1c4b51ccfeb 100644 --- a/engine-rest/engine-rest-openapi/src/main/templates/lib/commons/history-process-instance.ftl +++ b/engine-rest/engine-rest-openapi/src/main/templates/lib/commons/history-process-instance.ftl @@ -237,6 +237,13 @@ "desc": "Only include historic process instances which belong to no tenant. Value may only be `true`, as `false` is the default behavior." }, + "activityIdIn": { + "type": "array", + "itemType": "string", + "desc": "Restrict to instances that have an active activity or failing activity with one of given ids. It works + similarly to the activityIdIn filter in the runtime query. ${listTypeDescription}" + }, + "executedActivityIdIn": { "type": "array", "itemType": "string", diff --git a/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/dto/history/HistoricProcessInstanceQueryDto.java b/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/dto/history/HistoricProcessInstanceQueryDto.java index da4e861a544..c40ff2b28ea 100644 --- a/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/dto/history/HistoricProcessInstanceQueryDto.java +++ b/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/dto/history/HistoricProcessInstanceQueryDto.java @@ -109,6 +109,7 @@ public class HistoricProcessInstanceQueryDto extends AbstractQueryDto executedActivityIdIn; private List activeActivityIdIn; + private List activityIdIn; private Boolean active; private Boolean suspended; private Boolean completed; @@ -342,6 +343,11 @@ public void setActiveActivityIdIn(List activeActivityIdIn) { this.activeActivityIdIn = activeActivityIdIn; } + @CamundaQueryParam(value = "activityIdIn", converter = StringListConverter.class) + public void setactivityIdIn(List activityIdIn) { + this.activityIdIn = activityIdIn; + } + @CamundaQueryParam(value = "executedJobAfter", converter = DateConverter.class) public void setExecutedJobAfter(Date executedJobAfter) { this.executedJobAfter = executedJobAfter; @@ -548,6 +554,10 @@ protected void applyFilters(HistoricProcessInstanceQuery query) { query.activeActivityIdIn(activeActivityIdIn.toArray(new String[0])); } + if(activityIdIn!= null && !activityIdIn.isEmpty()) { + query.activityIdIn(activityIdIn.toArray(new String[0])); + } + if (executedJobAfter != null) { query.executedJobAfter(executedJobAfter); } diff --git a/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/history/HistoricProcessInstanceRestServiceQueryTest.java b/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/history/HistoricProcessInstanceRestServiceQueryTest.java index b5734cc32f0..7ed79ed567b 100644 --- a/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/history/HistoricProcessInstanceRestServiceQueryTest.java +++ b/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/history/HistoricProcessInstanceRestServiceQueryTest.java @@ -74,6 +74,7 @@ public class HistoricProcessInstanceRestServiceQueryTest extends AbstractRestSer protected static final String QUERY_PARAM_EXECUTED_ACTIVITY_IDS = "executedActivityIdIn"; protected static final String QUERY_PARAM_ACTIVE_ACTIVITY_IDS = "activeActivityIdIn"; protected static final String QUERY_PARAM_INCIDENT_IDS = "incidentIdIn"; + protected static final String QUERY_PARAM_ACTIVE_OR_FAILING_ACTIVITY_IDS = "activityIdIn"; @ClassRule public static TestContainerRule rule = new TestContainerRule(); @@ -2346,4 +2347,32 @@ public void testQueryByIncidentIdInAsPost() { verify(mockedQuery).incidentIdIn("1", "2"); } + @Test + public void testQueryByActivityIdIn() { + given() + .queryParam(QUERY_PARAM_ACTIVE_OR_FAILING_ACTIVITY_IDS, "1,2") + .then().expect() + .statusCode(Status.OK.getStatusCode()) + .when() + .get(HISTORIC_PROCESS_INSTANCE_RESOURCE_URL); + + verify(mockedQuery).activityIdIn("1", "2"); + } + + @Test + public void testQueryByActivityIdInAsPost() { + Map> parameters = new HashMap>(); + parameters.put(QUERY_PARAM_ACTIVE_OR_FAILING_ACTIVITY_IDS, Arrays.asList("1", "2")); + + given() + .contentType(POST_JSON_CONTENT_TYPE) + .body(parameters) + .then().expect() + .statusCode(Status.OK.getStatusCode()) + .when() + .post(HISTORIC_PROCESS_INSTANCE_RESOURCE_URL); + + verify(mockedQuery).activityIdIn("1", "2"); + } + } diff --git a/engine/src/main/java/org/camunda/bpm/engine/history/HistoricProcessInstanceQuery.java b/engine/src/main/java/org/camunda/bpm/engine/history/HistoricProcessInstanceQuery.java index e8034aa7df9..9e4b957e366 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/history/HistoricProcessInstanceQuery.java +++ b/engine/src/main/java/org/camunda/bpm/engine/history/HistoricProcessInstanceQuery.java @@ -440,6 +440,11 @@ public interface HistoricProcessInstanceQuery extends Query + @@ -413,9 +414,13 @@ - + + + + + @@ -425,6 +430,11 @@ LEFT JOIN ${prefix}ACT_HI_ACTINST HAI ON HAI.PROC_INST_ID_ = SELF.ID_ + + + LEFT JOIN ${prefix}ACT_RU_JOB RU_JOB + ON RU_JOB.PROCESS_INSTANCE_ID_ = SELF.PROC_INST_ID_ + @@ -652,7 +651,7 @@ #{activityId} - ) OR RU_JOB.FAILED_ACT_ID_ IN + ) OR INCACT.ACTIVITY_ID_ IN #{activityId} diff --git a/engine/src/test/java/org/camunda/bpm/engine/test/history/HistoricProcessInstanceTest.java b/engine/src/test/java/org/camunda/bpm/engine/test/history/HistoricProcessInstanceTest.java index 5d54af2c6c5..a342a9ff0e7 100644 --- a/engine/src/test/java/org/camunda/bpm/engine/test/history/HistoricProcessInstanceTest.java +++ b/engine/src/test/java/org/camunda/bpm/engine/test/history/HistoricProcessInstanceTest.java @@ -60,6 +60,7 @@ import org.camunda.bpm.engine.history.HistoricVariableInstance; import org.camunda.bpm.engine.impl.history.HistoryLevel; import org.camunda.bpm.engine.impl.history.event.HistoricProcessInstanceEventEntity; +import org.camunda.bpm.engine.impl.persistence.entity.JobEntity; import org.camunda.bpm.engine.impl.util.ClockUtil; import org.camunda.bpm.engine.repository.ProcessDefinition; import org.camunda.bpm.engine.runtime.Incident; @@ -70,9 +71,11 @@ import org.camunda.bpm.engine.test.Deployment; import org.camunda.bpm.engine.test.ProcessEngineRule; import org.camunda.bpm.engine.test.RequiredHistoryLevel; +import org.camunda.bpm.engine.test.api.mgmt.FailingDelegate; import org.camunda.bpm.engine.test.api.runtime.migration.models.CallActivityModels; import org.camunda.bpm.engine.test.api.runtime.migration.models.CompensationModels; import org.camunda.bpm.engine.test.api.runtime.migration.models.ProcessModels; +import org.camunda.bpm.engine.test.api.runtime.util.ChangeVariablesDelegate; import org.camunda.bpm.engine.test.util.ProcessEngineTestRule; import org.camunda.bpm.engine.test.util.ProvidedProcessEngineRule; import org.camunda.bpm.engine.variable.Variables; @@ -2081,6 +2084,44 @@ public void shouldQueryByActivityIdInWithMultipleScope() { .containsExactlyInAnyOrderElementsOf(Arrays.asList(processInstance.getId(), processInstance2.getId())); } + @Test + @RequiredHistoryLevel(ProcessEngineConfiguration.HISTORY_FULL) + public void shouldQueryByActivityIdWhereIncidentOccurred() { + // given + testHelper.deploy(Bpmn.createExecutableProcess("process") + .startEvent() + .serviceTask("theTask") + .camundaAsyncBefore() + .camundaClass(ChangeVariablesDelegate.class) + .serviceTask("theTask2").camundaClass(ChangeVariablesDelegate.class) + .serviceTask("theTask3").camundaClass(FailingDelegate.class) + .endEvent() + .done()); + + runtimeService.startProcessInstanceByKey("process", Variables.createVariables().putValue("fail", true)); + JobEntity job = (JobEntity) managementService.createJobQuery().singleResult(); + + // when: incident is raised + for(int i = 0; i<3; i++) { + try { + managementService.executeJob(job.getId()); + fail("Exception expected"); + } catch (Exception e) { + // exception expected + } + } + + // then + HistoricProcessInstance theTask = historyService.createHistoricProcessInstanceQuery() + .activityIdIn("theTask") + .singleResult(); + assertThat(theTask).isNotNull(); + HistoricProcessInstance theTask3 = historyService.createHistoricProcessInstanceQuery() + .activityIdIn("theTask3") + .singleResult(); + assertThat(theTask3).isNull(); + } + @Test public void testHistoricProcInstQueryWithActiveActivityIdsNull() { try { From e6dc4375d91e094105f795cceadeceffecff800b Mon Sep 17 00:00:00 2001 From: Gergely Juhasz Date: Fri, 20 Sep 2024 14:09:51 +0200 Subject: [PATCH 11/11] Apply suggestions from code review Co-authored-by: tasso94 <3015690+tasso94@users.noreply.github.com> --- .../src/main/templates/lib/commons/history-process-instance.ftl | 2 +- .../bpm/engine/history/HistoricProcessInstanceQuery.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/engine-rest/engine-rest-openapi/src/main/templates/lib/commons/history-process-instance.ftl b/engine-rest/engine-rest-openapi/src/main/templates/lib/commons/history-process-instance.ftl index d910bdfdb30..d5532b1cf92 100644 --- a/engine-rest/engine-rest-openapi/src/main/templates/lib/commons/history-process-instance.ftl +++ b/engine-rest/engine-rest-openapi/src/main/templates/lib/commons/history-process-instance.ftl @@ -240,7 +240,7 @@ "activityIdIn": { "type": "array", "itemType": "string", - "desc": "Restrict to instances that have an active activity or failing activity with one of the given ids. ${listTypeDescription}" + "desc": "Restrict to instances with an active activity with one of the given ids. This filter behaves differently as `activeActivityIdIn` since it also yields results when filtering for activities with an incident. ${listTypeDescription}" }, "executedActivityIdIn": { diff --git a/engine/src/main/java/org/camunda/bpm/engine/history/HistoricProcessInstanceQuery.java b/engine/src/main/java/org/camunda/bpm/engine/history/HistoricProcessInstanceQuery.java index 664ba891b1f..46fa51c951c 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/history/HistoricProcessInstanceQuery.java +++ b/engine/src/main/java/org/camunda/bpm/engine/history/HistoricProcessInstanceQuery.java @@ -441,7 +441,7 @@ public interface HistoricProcessInstanceQuery extends Query