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

feature(engine): add activityIdIn filter to HistoricProcessInstanceQuery #4619

Merged
Merged
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 @@ -237,6 +237,12 @@
"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 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": {
"type": "array",
"itemType": "string",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ public class HistoricProcessInstanceQueryDto extends AbstractQueryDto<HistoricPr
private Boolean withoutTenantId;
private List<String> executedActivityIdIn;
private List<String> activeActivityIdIn;
private List<String> activityIdIn;
private Boolean active;
private Boolean suspended;
private Boolean completed;
Expand Down Expand Up @@ -342,6 +343,11 @@ public void setActiveActivityIdIn(List<String> activeActivityIdIn) {
this.activeActivityIdIn = activeActivityIdIn;
}

@CamundaQueryParam(value = "activityIdIn", converter = StringListConverter.class)
public void setActivityIdIn(List<String> activityIdIn) {
this.activityIdIn = activityIdIn;
}

@CamundaQueryParam(value = "executedJobAfter", converter = DateConverter.class)
public void setExecutedJobAfter(Date executedJobAfter) {
this.executedJobAfter = executedJobAfter;
Expand Down Expand Up @@ -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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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<String, List<String>> parameters = new HashMap<String, List<String>>();
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");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,11 @@ public interface HistoricProcessInstanceQuery extends Query<HistoricProcessInsta
*/
HistoricProcessInstanceQuery activeActivityIdIn(String... ids);

/**
* Only select historic process 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.
*/
HistoricProcessInstanceQuery activityIdIn(String... ids);

/**
* Only select historic process instances that executed an job after the given date.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ public class HistoricProcessInstanceQueryImpl extends AbstractVariableQueryImpl<
protected boolean isTenantIdSet;
protected String[] executedActivityIds;
protected String[] activeActivityIds;
protected String[] activityIds;
protected String state;
protected String[] incidentIds;

Expand Down Expand Up @@ -478,6 +479,10 @@ public String[] getActiveActivityIds() {
return activeActivityIds;
}

public String[] getActivityIds() {
return activityIds;
}

public String getBusinessKey() {
return businessKey;
}
Expand Down Expand Up @@ -781,6 +786,14 @@ public HistoricProcessInstanceQuery activeActivityIdIn(String... ids) {
return this;
}

@Override
public HistoricProcessInstanceQuery activityIdIn(String... ids) {
ensureNotNull(BadUserRequestException.class, "activity ids", (Object[]) ids);
ensureNotContainsNull(BadUserRequestException.class, "activity ids", Arrays.asList(ids));
this.activityIds = ids;
return this;
}

@Override
public HistoricProcessInstanceQuery active() {
ensureNull(BadUserRequestException.class, "Already querying for historic process instance with another state", state, state);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@

<update id="updateHistoricProcessInstanceByProcessInstanceId"
parameterType="java.util.Map">
update
update
<if test="maxResults != null">
${limitBeforeWithoutOffset}
</if>
Expand Down Expand Up @@ -317,7 +317,7 @@
<result property="state" column="STATE_" jdbcType="VARCHAR"/>
<result property="restartedProcessInstanceId" column="RESTARTED_PROC_INST_ID_" jdbcType="VARCHAR"/>
</resultMap>

<resultMap type="org.camunda.bpm.engine.impl.util.ImmutablePair" id="deploymentIdMapping">
<id property="left" column="DEPLOYMENT_ID_" jdbcType="VARCHAR" />
<id property="right" column="ID_" jdbcType="VARCHAR" />
Expand Down Expand Up @@ -366,7 +366,7 @@
<include refid="selectHistoricProcessInstancesByQueryCriteriaSql"/>
${countDistinctAfterEnd}
</select>

<select id="selectHistoricProcessInstanceDeploymentIdMappingsByQueryCriteria" parameterType="org.camunda.bpm.engine.impl.HistoricProcessInstanceQueryImpl" resultMap="deploymentIdMapping">
select distinct RES.DEPLOYMENT_ID_, RES.ID_
<include refid="selectHistoricProcessInstancesByQueryCriteriaSql"/>
Expand Down Expand Up @@ -402,6 +402,7 @@

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

<foreach collection="queries" item="query">
Expand All @@ -413,9 +414,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)">
<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)">
<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" />
</if>
</foreach>

<if test="INC_JOIN">
Expand All @@ -425,8 +430,12 @@
LEFT JOIN ${prefix}ACT_HI_ACTINST HAI
ON HAI.PROC_INST_ID_ = SELF.ID_
</if>

<!-- actual value conditions are checked in the WHERE part;

<if test="INCACT_JOIN">
LEFT JOIN ${prefix}ACT_HI_INCIDENT INCACT on SELF.PROC_INST_ID_ = INCACT.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
names for the respective conditions (i.e. VI0, VI1, VI2, ...) -->
Expand Down Expand Up @@ -634,6 +643,21 @@
)
</if>

<if test="query.activityIds != null and query.activityIds.length > 0">
Copy link
Member

Choose a reason for hiding this comment

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

❓ Do we need to consider adding some indexes here? To ensure performance for the modification. Or the existing indexes will be good enough?

Copy link
Member

Choose a reason for hiding this comment

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

Let's be careful with indices on history tables. I would only add them when we get feedback. Adding a new index for existing databases with tables that have huge amounts of data is a costly operation, and it slows down process execution since history insertion is slower.

${queryType} (
(
HAI.END_TIME_ IS NULL
AND HAI.ACT_ID_ IN
<foreach item="activityId" index="index" collection="query.activityIds" open="(" separator="," close=")">
#{activityId}
</foreach>
) OR INCACT.ACTIVITY_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">
${queryType} (
HAI.END_TIME_ IS NOT NULL
Expand Down
Loading