From 7fa42a5fc1fdaf47f31c94cc84dfecc2b249f3a2 Mon Sep 17 00:00:00 2001 From: "Mannuru, ReddyKishore" Date: Tue, 28 May 2024 14:29:53 -0600 Subject: [PATCH] Fix get historic process instance api orquery for mutiple statues and withIncidents combined with orQuery --- ...essInstanceRestServiceInteractionTest.java | 8 +- .../HistoricProcessInstanceQueryImpl.java | 36 ++-- .../bpm/engine/impl/util/EnsureUtil.java | 8 + .../entity/HistoricProcessInstance.xml | 17 +- .../HistoricProcessInstanceQueryOrTest.java | 185 ++++++++++++++++++ 5 files changed, 231 insertions(+), 23 deletions(-) diff --git a/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/history/HistoricProcessInstanceRestServiceInteractionTest.java b/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/history/HistoricProcessInstanceRestServiceInteractionTest.java index 35741eeb572..2f3ba2c8dfe 100644 --- a/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/history/HistoricProcessInstanceRestServiceInteractionTest.java +++ b/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/history/HistoricProcessInstanceRestServiceInteractionTest.java @@ -44,6 +44,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.HashSet; import javax.ws.rs.core.Response.Status; import org.camunda.bpm.engine.AuthorizationException; import org.camunda.bpm.engine.BadUserRequestException; @@ -549,11 +550,7 @@ public void testOrQuery() { // given HistoricProcessInstanceQueryImpl mockedQuery = mock(HistoricProcessInstanceQueryImpl.class); when(historyServiceMock.createHistoricProcessInstanceQuery()).thenReturn(mockedQuery); - - String payload = "{ \"orQueries\": [{" + - "\"processDefinitionKey\": \"aKey\", " + - "\"processInstanceBusinessKey\": \"aBusinessKey\"}] }"; - + String payload = "{\"orQueries\": [{ \"processDefinitionKey\": \"aKey\", \"processInstanceBusinessKey\": \"aBusinessKey\", \"completed\": true ,\"active\": true}]}"; // when given() .contentType(POST_JSON_CONTENT_TYPE) @@ -572,6 +569,7 @@ public void testOrQuery() { // then assertThat(argument.getValue().getProcessDefinitionKey()).isEqualTo("aKey"); assertThat(argument.getValue().getBusinessKey()).isEqualTo("aBusinessKey"); + assertThat(argument.getValue().getState()).isEqualTo(new HashSet<>(Arrays.asList("COMPLETED", "ACTIVE"))); } protected void verifyBatchJson(String batchJson) { diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/HistoricProcessInstanceQueryImpl.java b/engine/src/main/java/org/camunda/bpm/engine/impl/HistoricProcessInstanceQueryImpl.java index 324a98c4e42..1f950760fb9 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/HistoricProcessInstanceQueryImpl.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/HistoricProcessInstanceQueryImpl.java @@ -20,7 +20,7 @@ import static org.camunda.bpm.engine.impl.util.EnsureUtil.ensureNotContainsNull; import static org.camunda.bpm.engine.impl.util.EnsureUtil.ensureNotEmpty; import static org.camunda.bpm.engine.impl.util.EnsureUtil.ensureNotNull; -import static org.camunda.bpm.engine.impl.util.EnsureUtil.ensureNull; +import static org.camunda.bpm.engine.impl.util.EnsureUtil.ensureEmpty; import java.util.ArrayList; import java.util.Arrays; @@ -91,7 +91,7 @@ public class HistoricProcessInstanceQueryImpl extends AbstractVariableQueryImpl< protected boolean isTenantIdSet; protected String[] executedActivityIds; protected String[] activeActivityIds; - protected String state; + protected Set state = new HashSet<>(); protected String caseInstanceId; @@ -599,7 +599,7 @@ public String getIncidentStatus() { return incidentStatus; } - public String getState() { + public Set getState() { return state; } @@ -772,36 +772,46 @@ public HistoricProcessInstanceQuery activeActivityIdIn(String... ids) { @Override public HistoricProcessInstanceQuery active() { - ensureNull(BadUserRequestException.class, "Already querying for historic process instance with another state", state, state); - state = HistoricProcessInstance.STATE_ACTIVE; + if(!isOrQueryActive) { + ensureEmpty(BadUserRequestException.class, "Already querying for historic process instance with another state", state); + } + state.add(HistoricProcessInstance.STATE_ACTIVE); return this; } @Override public HistoricProcessInstanceQuery suspended() { - ensureNull(BadUserRequestException.class, "Already querying for historic process instance with another state", state, state); - state = HistoricProcessInstance.STATE_SUSPENDED; + if(!isOrQueryActive) { + ensureEmpty(BadUserRequestException.class, "Already querying for historic process instance with another state", state); + } + state.add(HistoricProcessInstance.STATE_SUSPENDED); return this; } @Override public HistoricProcessInstanceQuery completed() { - ensureNull(BadUserRequestException.class, "Already querying for historic process instance with another state", state, state); - state = HistoricProcessInstance.STATE_COMPLETED; + if(!isOrQueryActive) { + ensureEmpty(BadUserRequestException.class, "Already querying for historic process instance with another state", state); + } + state.add(HistoricProcessInstance.STATE_COMPLETED); return this; } @Override public HistoricProcessInstanceQuery externallyTerminated() { - ensureNull(BadUserRequestException.class, "Already querying for historic process instance with another state", state, state); - state = HistoricProcessInstance.STATE_EXTERNALLY_TERMINATED; + if(!isOrQueryActive) { + ensureEmpty(BadUserRequestException.class, "Already querying for historic process instance with another state", state); + } + state.add(HistoricProcessInstance.STATE_EXTERNALLY_TERMINATED); return this; } @Override public HistoricProcessInstanceQuery internallyTerminated() { - ensureNull(BadUserRequestException.class, "Already querying for historic process instance with another state", state, state); - state = HistoricProcessInstance.STATE_INTERNALLY_TERMINATED; + if(!isOrQueryActive) { + ensureEmpty(BadUserRequestException.class, "Already querying for historic process instance with another state", state); + } + state.add(HistoricProcessInstance.STATE_INTERNALLY_TERMINATED); return this; } diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/util/EnsureUtil.java b/engine/src/main/java/org/camunda/bpm/engine/impl/util/EnsureUtil.java index 7664fdc1734..52d49757521 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/util/EnsureUtil.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/util/EnsureUtil.java @@ -127,6 +127,14 @@ public static void ensureNotEmpty(Class except } } + @SuppressWarnings("rawtypes") + public static void ensureEmpty(Class exceptionClass, String message, Collection collection) { + if (collection != null && !collection.isEmpty()) { + String variableName = collection.iterator().next().toString(); + throw generateException(exceptionClass, message, variableName, "is not empty"); + } + } + @SuppressWarnings("rawtypes") public static void ensureNotEmpty(String variableName, Map map) { ensureNotEmpty("", variableName, map); diff --git a/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/HistoricProcessInstance.xml b/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/HistoricProcessInstance.xml index 1e4503655eb..bce6e3cdb41 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/HistoricProcessInstance.xml +++ b/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/HistoricProcessInstance.xml @@ -402,12 +402,12 @@ - - - + + + @@ -516,8 +516,15 @@ ) - - ${queryType} SELF.STATE_ = #{query.state} + + + ${queryType} ( + SELF.STATE_ IS NOT NULL + AND SELF.STATE_ IN + + #{state} + + ) diff --git a/engine/src/test/java/org/camunda/bpm/engine/test/history/HistoricProcessInstanceQueryOrTest.java b/engine/src/test/java/org/camunda/bpm/engine/test/history/HistoricProcessInstanceQueryOrTest.java index f7516c7a945..564d2e36157 100644 --- a/engine/src/test/java/org/camunda/bpm/engine/test/history/HistoricProcessInstanceQueryOrTest.java +++ b/engine/src/test/java/org/camunda/bpm/engine/test/history/HistoricProcessInstanceQueryOrTest.java @@ -623,6 +623,106 @@ public void shouldReturnHistoricProcInstWithProcessDefinitionNameOrProcessDefini assertEquals(2, processInstances.size()); } + @Test + public void shouldReturnHistoricProcInstWithMultipleStates() { + // given + BpmnModelInstance aProcessDefinition = Bpmn.createExecutableProcess("aProcessDefinition") + .name("process1") + .startEvent() + .userTask() + .endEvent() + .done(); + + String deploymentId = repositoryService + .createDeployment() + .addModelInstance("foo.bpmn", aProcessDefinition) + .deploy() + .getId(); + + deploymentIds.add(deploymentId); + + ProcessInstance processInstance1 = runtimeService.startProcessInstanceByKey("aProcessDefinition"); + + BpmnModelInstance anotherProcessDefinition = Bpmn.createExecutableProcess("anotherProcessDefinition") + .startEvent() + .userTask() + .endEvent() + .done(); + + deploymentId = repositoryService + .createDeployment() + .addModelInstance("foo.bpmn", anotherProcessDefinition) + .deploy() + .getId(); + + deploymentIds.add(deploymentId); + + runtimeService.startProcessInstanceByKey("anotherProcessDefinition"); + runtimeService.updateProcessInstanceSuspensionState() + .byProcessInstanceId(processInstance1.getId()).suspend(); + + // when + List processInstances = historyService.createHistoricProcessInstanceQuery() + .or() + .active() + .suspended() + .endOr() + .list(); + + // then + assertEquals(2, processInstances.size()); + } + + @Test + public void shouldReturnHistoricProcInstWithMatchingState() { + // given + BpmnModelInstance aProcessDefinition = Bpmn.createExecutableProcess("aProcessDefinition") + .name("process1") + .startEvent() + .userTask() + .endEvent() + .done(); + + String deploymentId = repositoryService + .createDeployment() + .addModelInstance("foo.bpmn", aProcessDefinition) + .deploy() + .getId(); + + deploymentIds.add(deploymentId); + + ProcessInstance processInstance1 = runtimeService.startProcessInstanceByKey("aProcessDefinition"); + + BpmnModelInstance anotherProcessDefinition = Bpmn.createExecutableProcess("anotherProcessDefinition") + .startEvent() + .userTask() + .endEvent() + .done(); + + deploymentId = repositoryService + .createDeployment() + .addModelInstance("foo.bpmn", anotherProcessDefinition) + .deploy() + .getId(); + + deploymentIds.add(deploymentId); + + runtimeService.startProcessInstanceByKey("anotherProcessDefinition"); + runtimeService.updateProcessInstanceSuspensionState() + .byProcessInstanceId(processInstance1.getId()).suspend(); + + // when + List processInstances = historyService.createHistoricProcessInstanceQuery() + .or() + .active() + .endOr() + .list(); + + // then + assertEquals(1, processInstances.size()); + assertEquals("ACTIVE", processInstances.get(0).getState()); + } + @Test public void shouldReturnHistoricProcInstWithBusinessKeyOrBusinessKeyLike() { // given @@ -817,4 +917,89 @@ public void shouldReturnByProcessDefinitionIdOrIncidentType() { assertThat(processInstances.size()).isEqualTo(2); } + @Test + @Deployment(resources={"org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml"}) + public void shouldReturnHistoricProcInstWithVarValue1OrVarValue21() { + // given + Map vars = new HashMap(); + vars.put("stringVar", "abcdef"); + runtimeService.startProcessInstanceByKey("oneTaskProcess", vars); + + runtimeService.startProcessInstanceByKey("oneTaskProcess"); + + String processKey = "process"; + deployFailingProcess(processKey); + + vars = new HashMap(); + vars.put("stringVar", "ghijkl"); + runtimeService.startProcessInstanceByKey(processKey, vars); + + String jobId = managementService.createJobQuery().singleResult().getId(); + + managementService.setJobRetries(jobId, 0); + + // when + List processInstances = historyService.createHistoricProcessInstanceQuery() + .withIncidents() + .or() + .variableValueEquals("stringVar", "abcdef") + .variableValueEquals("stringVar", "ghijkl") + .endOr() + .list(); + + // then + assertEquals(1, processInstances.size()); + } + + protected void deployFailingProcess(String processKey) { + BpmnModelInstance aProcessDefinition = Bpmn.createExecutableProcess(processKey) + .startEvent() + .serviceTask() + .camundaClass("org.camunda.bpm.engine.test.jobexecutor.FailingDelegate") + .camundaAsyncBefore() + .endEvent() + .done(); + + String deploymentId = repositoryService + .createDeployment() + .addModelInstance("foo.bpmn", aProcessDefinition) + .deploy() + .getId(); + + deploymentIds.add(deploymentId); + } + + @Test + @Deployment(resources={"org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml"}) + public void shouldReturnHistoricProcInstWithVarValue1OrVarValue23() { + // given + Map vars = new HashMap(); + vars.put("stringVar", "abcdef"); + runtimeService.startProcessInstanceByKey("oneTaskProcess", vars); + + runtimeService.startProcessInstanceByKey("oneTaskProcess"); + + String processKey = "process"; + deployFailingProcess(processKey); + + vars = new HashMap(); + vars.put("stringVar", "ghijkl"); + runtimeService.startProcessInstanceByKey(processKey, vars); + + String jobId = managementService.createJobQuery().singleResult().getId(); + + managementService.setJobRetries(jobId, 0); + + // when + List processInstances = historyService.createHistoricProcessInstanceQuery() + .or() + .withIncidents() + .variableValueEquals("stringVar", "abcdef") + .endOr() + .list(); + + // then + assertEquals(1, processInstances.size()); + } + }