From f315a98d04bd13e83758c83aaa4a656e29bd2e90 Mon Sep 17 00:00:00 2001 From: Tobias Metzke Date: Fri, 24 Jan 2020 15:08:03 +0100 Subject: [PATCH] feat(engine+rest): add job query filter for failed activity related to CAM-11273 --- .../dto/history/HistoricJobLogQueryDto.java | 11 ++++- .../engine/rest/dto/runtime/JobQueryDto.java | 12 ++++- .../engine/rest/JobRestServiceQueryTest.java | 2 + .../HistoricJobLogRestServiceQueryTest.java | 4 ++ .../engine/history/HistoricJobLogQuery.java | 3 ++ .../engine/impl/HistoricJobLogQueryImpl.java | 13 +++++ .../camunda/bpm/engine/impl/JobQueryImpl.java | 7 +++ .../camunda/bpm/engine/runtime/JobQuery.java | 3 ++ .../impl/mapping/entity/HistoricJobLog.xml | 7 +++ .../bpm/engine/impl/mapping/entity/Job.xml | 3 ++ .../engine/test/api/mgmt/JobQueryTest.java | 24 ++++++++++ .../test/history/HistoricJobLogQueryTest.java | 48 +++++++++++++++++++ 12 files changed, 135 insertions(+), 2 deletions(-) diff --git a/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/dto/history/HistoricJobLogQueryDto.java b/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/dto/history/HistoricJobLogQueryDto.java index 348813bc5b6..34497bb8a9e 100644 --- a/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/dto/history/HistoricJobLogQueryDto.java +++ b/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/dto/history/HistoricJobLogQueryDto.java @@ -31,7 +31,6 @@ import org.camunda.bpm.engine.rest.dto.converter.BooleanConverter; import org.camunda.bpm.engine.rest.dto.converter.LongConverter; import org.camunda.bpm.engine.rest.dto.converter.StringArrayConverter; -import org.camunda.bpm.engine.rest.dto.converter.StringConverter; import org.camunda.bpm.engine.rest.dto.converter.StringListConverter; import com.fasterxml.jackson.databind.ObjectMapper; @@ -86,6 +85,7 @@ public class HistoricJobLogQueryDto extends AbstractQueryDto 0) { + query.failedActivityIdIn(failedActivityIds); + } + if (executionIds != null && executionIds.length > 0) { query.executionIdIn(executionIds); } diff --git a/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/dto/runtime/JobQueryDto.java b/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/dto/runtime/JobQueryDto.java index d9e325870a9..b8cf24c1d2a 100644 --- a/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/dto/runtime/JobQueryDto.java +++ b/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/dto/runtime/JobQueryDto.java @@ -79,6 +79,7 @@ public class JobQueryDto extends AbstractQueryDto { protected Boolean messages; protected Boolean withException; protected String exceptionMessage; + protected String failedActivityId; protected Boolean noRetriesLeft; protected Boolean active; protected Boolean suspended; @@ -103,6 +104,11 @@ public void setActivityId(String activityId) { this.activityId = activityId; } + @CamundaQueryParam("failedActivityId") + public void setFailedActivityId(String activityId) { + this.failedActivityId = activityId; + } + @CamundaQueryParam("jobId") public void setJobId(String jobId) { this.jobId = jobId; @@ -257,7 +263,7 @@ void run(List dates) { abstract void setLowerThan(Date date); } - + @Override protected void applyFilters(final JobQuery query) { if (activityId != null){ @@ -314,6 +320,10 @@ protected void applyFilters(final JobQuery query) { query.exceptionMessage(exceptionMessage); } + if (failedActivityId != null) { + query.failedActivityId(failedActivityId); + } + if (TRUE.equals(noRetriesLeft)) { query.noRetriesLeft(); } diff --git a/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/JobRestServiceQueryTest.java b/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/JobRestServiceQueryTest.java index 7774b4f2033..438ed04aad1 100644 --- a/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/JobRestServiceQueryTest.java +++ b/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/JobRestServiceQueryTest.java @@ -409,6 +409,7 @@ private Map getCompleteParameters() { parameters.put("timers", MockProvider.EXAMPLE_TIMERS); parameters.put("withException", MockProvider.EXAMPLE_WITH_EXCEPTION); parameters.put("exceptionMessage", MockProvider.EXAMPLE_EXCEPTION_MESSAGE); + parameters.put("failedActivityId", MockProvider.EXAMPLE_JOB_FAILED_ACTIVITY_ID); parameters.put("noRetriesLeft", MockProvider.EXAMPLE_NO_RETRIES_LEFT); parameters.put("active", true); parameters.put("suspended", true); @@ -445,6 +446,7 @@ private void verifyParameterQueryInvocations() { verify(mockQuery).timers(); verify(mockQuery).withException(); verify(mockQuery).exceptionMessage((String) parameters.get("exceptionMessage")); + verify(mockQuery).failedActivityId((String) parameters.get("failedActivityId")); verify(mockQuery).noRetriesLeft(); verify(mockQuery).active(); verify(mockQuery).suspended(); diff --git a/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/history/HistoricJobLogRestServiceQueryTest.java b/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/history/HistoricJobLogRestServiceQueryTest.java index d2829a7be78..d6a693434d7 100644 --- a/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/history/HistoricJobLogRestServiceQueryTest.java +++ b/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/history/HistoricJobLogRestServiceQueryTest.java @@ -598,6 +598,7 @@ public void testListParameters() { given() .queryParam("activityIdIn", anActId + "," + anotherActId) .queryParam("executionIdIn", anExecutionId + "," + anotherExecutionId) + .queryParam("failedActivityIdIn", anActId + "," + anotherActId) .then() .expect() .statusCode(Status.OK.getStatusCode()) @@ -606,6 +607,7 @@ public void testListParameters() { verify(mockedQuery).activityIdIn(anActId, anotherActId); verify(mockedQuery).executionIdIn(anExecutionId, anotherExecutionId); + verify(mockedQuery).failedActivityIdIn(anActId, anotherActId); verify(mockedQuery).list(); } @@ -620,6 +622,7 @@ public void testListParametersAsPost() { Map> json = new HashMap>(); json.put("activityIdIn", Arrays.asList(anActId, anotherActId)); json.put("executionIdIn", Arrays.asList(anExecutionId, anotherExecutionId)); + json.put("failedActivityIdIn", Arrays.asList(anActId, anotherActId)); given() .contentType(POST_JSON_CONTENT_TYPE) @@ -632,6 +635,7 @@ public void testListParametersAsPost() { verify(mockedQuery).activityIdIn(anActId, anotherActId); verify(mockedQuery).executionIdIn(anExecutionId, anotherExecutionId); + verify(mockedQuery).failedActivityIdIn(anActId, anotherActId); verify(mockedQuery).list(); } diff --git a/engine/src/main/java/org/camunda/bpm/engine/history/HistoricJobLogQuery.java b/engine/src/main/java/org/camunda/bpm/engine/history/HistoricJobLogQuery.java index fc381d46acc..cad7ee9beb0 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/history/HistoricJobLogQuery.java +++ b/engine/src/main/java/org/camunda/bpm/engine/history/HistoricJobLogQuery.java @@ -45,6 +45,9 @@ public interface HistoricJobLogQuery extends Query activityIdList = CollectionUtil.asArrayList(activityIds); + ensureNotContainsNull("activityIds", activityIdList); + ensureNotContainsEmptyString("activityIds", activityIdList); + this.failedActivityIds = activityIds; + return this; + } + public HistoricJobLogQuery executionIdIn(String... executionIds) { List executionIdList = CollectionUtil.asArrayList(executionIds); ensureNotContainsNull("executionIds", executionIdList); @@ -323,6 +332,10 @@ public String[] getActivityIds() { return activityIds; } + public String[] getFailedActivityIds() { + return failedActivityIds; + } + public String[] getExecutionIds() { return executionIds; } diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/JobQueryImpl.java b/engine/src/main/java/org/camunda/bpm/engine/impl/JobQueryImpl.java index 0052a0b3ddc..0e39368e44a 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/JobQueryImpl.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/JobQueryImpl.java @@ -62,6 +62,7 @@ public class JobQueryImpl extends AbstractQuery implements JobQue protected Long priorityLowerThanOrEqual; protected boolean withException; protected String exceptionMessage; + protected String failedActivityId; protected boolean noRetriesLeft; protected SuspensionState suspensionState; @@ -211,6 +212,12 @@ public JobQuery exceptionMessage(String exceptionMessage) { return this; } + public JobQuery failedActivityId(String activityId){ + ensureNotNull("Provided activity id", activityId); + this.failedActivityId = activityId; + return this; + } + public JobQuery noRetriesLeft() { noRetriesLeft = true; return this; diff --git a/engine/src/main/java/org/camunda/bpm/engine/runtime/JobQuery.java b/engine/src/main/java/org/camunda/bpm/engine/runtime/JobQuery.java index 5473b754ac8..03982f53d92 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/runtime/JobQuery.java +++ b/engine/src/main/java/org/camunda/bpm/engine/runtime/JobQuery.java @@ -121,6 +121,9 @@ public interface JobQuery extends Query { /** Only select jobs that failed due to an exception with the given message. */ JobQuery exceptionMessage(String exceptionMessage); + /** Only select jobs that failed due to an exception at an activity with the given id. **/ + JobQuery failedActivityId(String activityId); + /** Only select jobs which have no retries left */ JobQuery noRetriesLeft(); diff --git a/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/HistoricJobLog.xml b/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/HistoricJobLog.xml index f4d51e96d73..200010322c5 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/HistoricJobLog.xml +++ b/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/HistoricJobLog.xml @@ -326,6 +326,13 @@ and RES.JOB_EXCEPTION_MSG_ = #{jobExceptionMessage} + + and RES.FAILED_ACT_ID_ in + + #{item} + + and RES.JOB_DEF_ID_ = #{jobDefinitionId} diff --git a/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/Job.xml b/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/Job.xml index 4048d817633..4d8cfb5b597 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/Job.xml +++ b/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/Job.xml @@ -360,6 +360,9 @@ and RES.EXCEPTION_MSG_ = #{exceptionMessage} + + and RES.FAILED_ACT_ID_ = #{failedActivityId} + and RES.RETRIES_ = 0 diff --git a/engine/src/test/java/org/camunda/bpm/engine/test/api/mgmt/JobQueryTest.java b/engine/src/test/java/org/camunda/bpm/engine/test/api/mgmt/JobQueryTest.java index d864953404d..91cc80d09ea 100644 --- a/engine/src/test/java/org/camunda/bpm/engine/test/api/mgmt/JobQueryTest.java +++ b/engine/src/test/java/org/camunda/bpm/engine/test/api/mgmt/JobQueryTest.java @@ -575,6 +575,30 @@ public void testQueryByExceptionMessageNull() { } } + @Test + @Deployment(resources = {"org/camunda/bpm/engine/test/api/mgmt/ManagementServiceTest.testGetJobExceptionStacktrace.bpmn20.xml"}) + public void testQueryByFailedActivityId(){ + JobQuery query = managementService.createJobQuery().failedActivityId("theScriptTask"); + verifyQueryResults(query, 0); + + ProcessInstance processInstance = startProcessInstanceWithFailingJob(); + + query = managementService.createJobQuery().failedActivityId("theScriptTask"); + verifyFailedJob(query, processInstance); + } + + @Test + public void testQueryByInvalidFailedActivityId(){ + JobQuery query = managementService.createJobQuery().failedActivityId("invalid"); + verifyQueryResults(query, 0); + + try { + managementService.createJobQuery().failedActivityId(null).list(); + fail(); + } catch (ProcessEngineException e) {} + } + + @Test public void testJobQueryWithExceptions() throws Throwable { diff --git a/engine/src/test/java/org/camunda/bpm/engine/test/history/HistoricJobLogQueryTest.java b/engine/src/test/java/org/camunda/bpm/engine/test/history/HistoricJobLogQueryTest.java index e55e7494761..727b4fc7efd 100644 --- a/engine/src/test/java/org/camunda/bpm/engine/test/history/HistoricJobLogQueryTest.java +++ b/engine/src/test/java/org/camunda/bpm/engine/test/history/HistoricJobLogQueryTest.java @@ -189,6 +189,54 @@ public void testQueryByInvalidJobExceptionMessage() { } } + @Deployment(resources = {"org/camunda/bpm/engine/test/history/HistoricJobLogTest.testAsyncContinuation.bpmn20.xml"}) + @Test + public void testQueryByFailedActivityId() { + runtimeService.startProcessInstanceByKey("process"); + String jobId = managementService.createJobQuery().singleResult().getId(); + try { + managementService.executeJob(jobId); + fail("exception expected"); + } catch (Exception e) { + // expected + } + + HistoricJobLogQuery query = historyService.createHistoricJobLogQuery().failedActivityIdIn("serviceTask"); + + verifyQueryResults(query, 1); + } + + @Test + public void testQueryByInvalidFailedActivityId() { + HistoricJobLogQuery query = historyService.createHistoricJobLogQuery().failedActivityIdIn("invalid"); + + verifyQueryResults(query, 0); + + String[] nullValue = null; + + try { + query.failedActivityIdIn(nullValue); + fail("exception expected"); + } catch (Exception e) { + } + + String[] activityIdsContainsNull = {"a", null, "b"}; + + try { + query.failedActivityIdIn(activityIdsContainsNull); + fail("exception expected"); + } catch (Exception e) { + } + + String[] activityIdsContainsEmptyString = {"a", "", "b"}; + + try { + query.failedActivityIdIn(activityIdsContainsEmptyString); + fail("exception expected"); + } catch (Exception e) { + } + } + @Deployment(resources = {"org/camunda/bpm/engine/test/history/HistoricJobLogTest.testAsyncContinuation.bpmn20.xml"}) @Test public void testQueryByJobDefinitionId() {