incubator-kie-kogito-runtimes icon indicating copy to clipboard operation
incubator-kie-kogito-runtimes copied to clipboard

Multiple return values from a service task do not update process variables

Open tokarenko opened this issue 2 years ago • 3 comments

Describe the bug

I set up service task to return two variables as follows:

  • Mapped service task outputs to process variables in "Data Outputs and Assignments" of BPMN editor;
  • Implemented service task handler to return java Map<String, Object>:
@ApplicationScoped
public class Handler {
  public Map<String, Object> Execute() {
    Map<String, Object> results = new HashMap<>();
    results.put("processVariableA", true);
    results.put("processVariableB", "message");
    return results;
  }
}

Solution compiles and runs but process variables do not update with results and process does not transition further the service task and remains in "active" state:

Starting workflow 'Provisioning' (8ce17dc5-9606-425b-b563-a9deacdcc812)
Triggered node 'Start' for process 'Provisioning' (8ce17dc5-9606-425b-b563-a9deacdcc812)
Triggered node 'Set Variables' for process 'Provisioning' (8ce17dc5-9606-425b-b563-a9deacdcc812)
Workflow 'PortsProvisioning' (8ce17dc5-9606-425b-b563-a9deacdcc812) was started, now 'ACTIVE'

I checked Kogito source code and found that there are functions to set and get results as Map<String, Object>: public void setResults(Map<String, Object> results) public Map<String, Object> getResults()

Expected behavior

Process variables update with results returned from service task as java Map<String, Object>

Actual behavior

Process variables do not update with results returned from service task as java Map<String, Object> and process does not transition further the service task and remains in "active" state

How to Reproduce?

No response

Output of uname -a or ver

No response

Output of java -version

openjdk version "17.0.4" 2022-07-19

GraalVM version (if different from Java)

No response

Kogito version or git rev (or at least Quarkus version if you are using Kogito via Quarkus platform BOM)

No response

Build tool (ie. output of mvnw --version or gradlew --version)

No response

Additional information

No response

tokarenko avatar Aug 24 '22 07:08 tokarenko

I suppose that the issue may be in ServiceTaskHandler.java

Current implementation puts result object into results HashMap with resultVarName irrespective of the fact that result may be itself a HashMap.

public class ServiceTaskHandler implements KogitoWorkItemHandler {
    ...
    private String resultVarName;
    ...
    public ServiceTaskHandler(String resultVarName) {
        this.resultVarName = resultVarName;
    }
    ...
    public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) {
    ...
    Object result = method.invoke(instance, params);
    Map<String, Object> results = new HashMap<>();
    results.put(resultVarName, result);
    manager.completeWorkItem(workItem.getStringId(), results);

tokarenko avatar Aug 24 '22 08:08 tokarenko

@tokarenko Im assuming you already check the service example https://github.com/kiegroup/kogito-examples/tree/stable/kogito-quarkus-examples/process-service-calls-quarkus This is a pretty tricky case. Right now, as you are experiencing, Kogito is not ready to handle that. Kogito is assuming that result is a singleton map that will be assigned to just one target variable image In order to support mapping more than one, we need first to decide how to write the output assigment. So rather than result to variable, we can either do result.keyInMap1 to varible1 and result.keyInMap1 to variable2 or a variation of that, for example keyInMap1 to variable1 and keyInMap2 to variable2 (this is my preferred option) Another option is to assume that if the service return a map, you should map whatever is inside the map to the variables, ignoring the outputassigment part, but this is not bpmn oriented and I do not think we should do that.

fjtirado avatar Aug 24 '22 09:08 fjtirado

Opened JIRA https://issues.redhat.com/browse/KOGITO-7844 to implement that @krisv any thought on that are welcome

fjtirado avatar Aug 24 '22 09:08 fjtirado

ServiceTask was designed to only return one result, as this matches with invoking a Java operation, which also just returns one Object. Automatically turning a HashMap into multiple results would be possible (and quite trivial), but it would be difficult for the engine to guess if that's what the process designer wants or not (as the other case where a hashmap is considered as one result might be valid too). A service task is nothing more than an implementation of a custom work item node, how about just having your own custom work item that does what you expect?

krisv avatar Apr 06 '23 11:04 krisv