Skip to content

Commit

Permalink
Add support for searching workflow instances by state variable key an…
Browse files Browse the repository at this point in the history
…d value via REST API
  • Loading branch information
Edvard Fonsell committed Jan 22, 2021
1 parent 335b3da commit cf1edf0
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 38 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@

**Highlights**
- Support updating workflow instance business key.
- Support for searching workflow instances by state variable key and value.

**Details**
- `nflow-engine`
- `WorkflowInstanceService.updateWorkflowInstance` can now be used to update business key of the workflow instance.
- `nflow-rest-api-common`
- Use `QueryWorkflowInstances.setStateVariable` to limit search query by state variable name and key. Only the latest value of the state variable of the workflow instance is used.
- `nflow-rest-api-common`, `nflow-rest-api-jax-rs`, `nflow-rest-api-spring-web`
- `UpdateWorkflowInstanceRequest.businessKey` field was added to support updating workflow instance business key via REST API.
- Added support for new query parameters `stateVariableKey` and `stateVariableValue` to `GET /v1/workflow-instance` to limit search query by state variable name and key. Only the latest value of the state variable of the workflow instance is used.
- `nflow-explorer`
- Dependency updates:
- urijs 1.19.5
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,27 +139,28 @@ public boolean updateWorkflowInstance(final long id,
return workflowInstances.updateWorkflowInstance(instance, action);
}

public Stream<ListWorkflowInstanceResponse> listWorkflowInstances(final List<Long> ids, final List<String> types,
final Long parentWorkflowId, final Long parentActionId, final List<String> states,
final List<WorkflowInstanceStatus> statuses, final String businessKey, final String externalId, final String include,
final Long maxResults, final Long maxActions, final WorkflowInstanceService workflowInstances,
final ListWorkflowInstanceConverter listWorkflowConverter) {
public Stream<ListWorkflowInstanceResponse> listWorkflowInstances(List<Long> ids, List<String> types, Long parentWorkflowId,
Long parentActionId, List<String> states, List<WorkflowInstanceStatus> statuses, String businessKey, String externalId,
String stateVariableKey, String stateVariableValue, String include, Long maxResults, Long maxActions,
WorkflowInstanceService workflowInstances, ListWorkflowInstanceConverter listWorkflowConverter) {
Set<String> includeStrings = parseIncludeStrings(include).collect(toSet());
QueryWorkflowInstances q = new QueryWorkflowInstances.Builder() //
.addIds(ids.toArray(new Long[ids.size()])) //
.addTypes(types.toArray(new String[types.size()])) //
.setParentWorkflowId(parentWorkflowId) //
.setParentActionId(parentActionId) //
.addStates(states.toArray(new String[states.size()])) //
.addStatuses(statuses.toArray(new WorkflowInstanceStatus[statuses.size()])) //
.setBusinessKey(businessKey) //
.setExternalId(externalId) //
.setIncludeCurrentStateVariables(includeStrings.contains(currentStateVariables)) //
.setIncludeActions(includeStrings.contains(actions)) //
.setIncludeActionStateVariables(includeStrings.contains(actionStateVariables)) //
.setMaxResults(maxResults) //
.setMaxActions(maxActions) //
.setIncludeChildWorkflows(includeStrings.contains(childWorkflows)).build();
QueryWorkflowInstances q = new QueryWorkflowInstances.Builder()
.addIds(ids.toArray(new Long[ids.size()]))
.addTypes(types.toArray(new String[types.size()]))
.setParentWorkflowId(parentWorkflowId)
.setParentActionId(parentActionId)
.addStates(states.toArray(new String[states.size()]))
.addStatuses(statuses.toArray(new WorkflowInstanceStatus[statuses.size()]))
.setBusinessKey(businessKey)
.setExternalId(externalId)
.setIncludeCurrentStateVariables(includeStrings.contains(currentStateVariables))
.setIncludeActions(includeStrings.contains(actions))
.setIncludeActionStateVariables(includeStrings.contains(actionStateVariables))
.setMaxResults(maxResults)
.setMaxActions(maxActions)
.setIncludeChildWorkflows(includeStrings.contains(childWorkflows))
.setStateVariable(stateVariableKey, stateVariableValue)
.build();
Stream<WorkflowInstance> instances = workflowInstances.listWorkflowInstancesAsStream(q);
Set<WorkflowInstanceInclude> parseIncludeEnums = parseIncludeEnums(include);
return instances.map(instance -> listWorkflowConverter.convert(instance, parseIncludeEnums));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,14 @@ public Response listWorkflowInstances(@QueryParam("id") @ApiParam("Internal id o
@QueryParam("status") @ApiParam("Current status of workflow instance") List<WorkflowInstanceStatus> statuses,
@QueryParam("businessKey") @ApiParam("Business key for workflow instance") String businessKey,
@QueryParam("externalId") @ApiParam("External id for workflow instance") String externalId,
@QueryParam("stateVariableKey") @ApiParam("Key of state variable that must exist for workflow instance") String stateVariableKey,
@QueryParam("stateVariableValue") @ApiParam("Current value of state variable defined by stateVariableKey") String stateVariableValue,
@QueryParam("include") @ApiParam(value = INCLUDE_PARAM_DESC, allowableValues = INCLUDE_PARAM_VALUES, allowMultiple = true) String include,
@QueryParam("maxResults") @ApiParam("Maximum number of workflow instances to be returned") Long maxResults,
@QueryParam("maxActions") @ApiParam("Maximum number of actions returned for each workflow instance") Long maxActions) {
return handleExceptions(() -> ok(super.listWorkflowInstances(ids, types, parentWorkflowId, parentActionId, states, statuses,
businessKey, externalId, include, maxResults, maxActions, workflowInstances, listWorkflowConverter).iterator()));
businessKey, externalId, stateVariableKey, stateVariableValue, include, maxResults, maxActions, workflowInstances,
listWorkflowConverter).iterator()));
}

@PUT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
Expand Down Expand Up @@ -212,29 +213,49 @@ public void whenUpdatingBusinessKeyWithDescriptionUpdateWorkflowInstanceWorks()
@Test
public void listWorkflowInstancesWorks() {
makeRequest(() -> resource.listWorkflowInstances(asList(42L), asList("type"), 99L, 88L, asList("state"),
asList(WorkflowInstanceStatus.created), "businessKey", "externalId", "", null, null));
verify(workflowInstances).listWorkflowInstancesAsStream((QueryWorkflowInstances) argThat(allOf(hasField("ids", contains(42L)),
hasField("types", contains("type")), hasField("parentWorkflowId", is(99L)), hasField("parentActionId", is(88L)),
hasField("states", contains("state")), hasField("statuses", contains(WorkflowInstanceStatus.created)),
hasField("businessKey", equalTo("businessKey")), hasField("externalId", equalTo("externalId")),
hasField("includeActions", equalTo(false)), hasField("includeCurrentStateVariables", equalTo(false)),
hasField("includeActionStateVariables", equalTo(false)), hasField("includeChildWorkflows", equalTo(false)),
hasField("maxResults", equalTo(null)), hasField("maxActions", equalTo(null)))));
asList(WorkflowInstanceStatus.created), "businessKey", "externalId", null, null, "", null, null));
verify(workflowInstances).listWorkflowInstancesAsStream((QueryWorkflowInstances) argThat(allOf(
hasField("ids", contains(42L)),
hasField("types", contains("type")),
hasField("parentWorkflowId", is(99L)),
hasField("parentActionId", is(88L)),
hasField("states", contains("state")),
hasField("statuses", contains(WorkflowInstanceStatus.created)),
hasField("businessKey", equalTo("businessKey")),
hasField("externalId", equalTo("externalId")),
hasField("stateVariableKey", nullValue()),
hasField("stateVariableValue", nullValue()),
hasField("includeActions", equalTo(false)),
hasField("includeCurrentStateVariables", equalTo(false)),
hasField("includeActionStateVariables", equalTo(false)),
hasField("includeChildWorkflows", equalTo(false)),
hasField("maxResults", equalTo(null)),
hasField("maxActions", equalTo(null)))));
}

@Test
public void listWorkflowInstancesWorksWithAllIncludes() {
makeRequest(() -> resource.listWorkflowInstances(asList(42L), asList("type"), 99L, 88L, asList("state"),
asList(WorkflowInstanceStatus.created, WorkflowInstanceStatus.executing), "businessKey", "externalId",
"actions,currentStateVariables,actionStateVariables,childWorkflows", 1L, 1L));
"stateVarKey", "stateVarValue", "actions,currentStateVariables,actionStateVariables,childWorkflows", 1L, 1L));
verify(workflowInstances).listWorkflowInstancesAsStream(
(QueryWorkflowInstances) argThat(allOf(hasField("ids", contains(42L)), hasField("types", contains("type")),
hasField("parentWorkflowId", is(99L)), hasField("parentActionId", is(88L)), hasField("states", contains("state")),
(QueryWorkflowInstances) argThat(allOf(
hasField("ids", contains(42L)),
hasField("types", contains("type")),
hasField("parentWorkflowId", is(99L)),
hasField("parentActionId", is(88L)),
hasField("states", contains("state")),
hasField("statuses", contains(WorkflowInstanceStatus.created, WorkflowInstanceStatus.executing)),
hasField("businessKey", equalTo("businessKey")), hasField("externalId", equalTo("externalId")),
hasField("includeActions", equalTo(true)), hasField("includeCurrentStateVariables", equalTo(true)),
hasField("includeActionStateVariables", equalTo(true)), hasField("includeChildWorkflows", equalTo(true)),
hasField("maxResults", equalTo(1L)), hasField("maxActions", equalTo(1L)))));
hasField("businessKey", equalTo("businessKey")),
hasField("externalId", equalTo("externalId")),
hasField("stateVariableKey", equalTo("stateVarKey")),
hasField("stateVariableValue", equalTo("stateVarValue")),
hasField("includeActions", equalTo(true)),
hasField("includeCurrentStateVariables", equalTo(true)),
hasField("includeActionStateVariables", equalTo(true)),
hasField("includeChildWorkflows", equalTo(true)),
hasField("maxResults", equalTo(1L)),
hasField("maxActions", equalTo(1L)))));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,15 @@ public Mono<ResponseEntity<?>> listWorkflowInstances(
@RequestParam(value = "status", defaultValue = "") @ApiParam("Current status of workflow instance") List<WorkflowInstanceStatus> statuses,
@RequestParam(value = "businessKey", required = false) @ApiParam("Business key for workflow instance") String businessKey,
@RequestParam(value = "externalId", required = false) @ApiParam("External id for workflow instance") String externalId,
@RequestParam(value = "stateVariableKey", required = false) @ApiParam("Key of state variable that must exist for workflow instance") String stateVariableKey,
@RequestParam(value = "stateVariableValue", required = false) @ApiParam("Current value of state variable defined by stateVariableKey") String stateVariableValue,
@RequestParam(value = "include", required = false) @ApiParam(value = INCLUDE_PARAM_DESC, allowableValues = INCLUDE_PARAM_VALUES, allowMultiple = true) String include,
@RequestParam(value = "maxResults", required = false) @ApiParam("Maximum number of workflow instances to be returned") Long maxResults,
@RequestParam(value = "maxActions", required = false) @ApiParam("Maximum number of actions returned for each workflow instance") Long maxActions) {
return handleExceptions(() -> wrapBlocking(
() -> ok(super.listWorkflowInstances(ids, types, parentWorkflowId, parentActionId, states, statuses, businessKey,
externalId, include, maxResults, maxActions, this.workflowInstances, this.listWorkflowConverter).iterator())));
externalId, stateVariableKey, stateVariableValue, include, maxResults, maxActions, this.workflowInstances,
this.listWorkflowConverter).iterator())));
}

@PutMapping(path = "/{id}/signal", consumes = APPLICATION_JSON_VALUE)
Expand Down

0 comments on commit cf1edf0

Please sign in to comment.