cancel
Showing results for 
Search instead for 
Did you mean: 

Variables Array Always Empty in REST 'Start a Process Instance' Resource Results

ryanj1
Champ in-the-making
Champ in-the-making
First, I'm using Activiti 5.15. (If this has been fixed in V5.15.1, let me know; my understanding is that version is exclusively for the MySQL 5.6 bug.)

When calling the "Start a Process Instance" REST resource, I noticed that the "variables" array was always empty, regardless of whether a process instance had associated variables or not and regardless of whether it was in process or completed. After looking into the code, it appeared that this snippet was causing the issue:

if (processInstance.getProcessVariables() != null) {
    Map<String, Object> variableMap = processInstance.getProcessVariables();
    for (String name : variableMap.keySet()) {
      result.addVariable(createRestVariable(securedResource, name, variableMap.get(name),
          RestVariableScope.LOCAL, processInstance.getId(), VARIABLE_PROCESS, false));
    }
  }

Of specific importance is the "processInstance.getProcessVariables()" call; it was always returning a Map with size 0.

I added the following code instead of the code above, and now the resource always returns a complete variable list:

RuntimeService runtimeService = ActivitiUtil.getRuntimeService();
    HistoryService historyService = ActivitiUtil.getHistoryService();
    if(processInstance.isEnded()) {
       //Process complete. Get variable values from the history service.
       result.setCompleted(true);
       
       Map<String, Object> variableMap = new HashMap<String, Object>();
       List<HistoricDetail> historicDetailList = historyService.createHistoricDetailQuery().executionId(processInstance.getId()).list();
       for(HistoricDetail historicDetail : historicDetailList) {
          Map<String, Integer> versionMap = new HashMap<String, Integer>();
          if(historicDetail instanceof HistoricVariableUpdate) {
             HistoricVariableUpdate historicVariableUpdate = (HistoricVariableUpdate) historicDetail;
             if(versionMap.get(historicVariableUpdate.getVariableName()) == null) {
                versionMap.put(historicVariableUpdate.getVariableName(), historicVariableUpdate.getRevision());
                variableMap.put(historicVariableUpdate.getVariableName(), historicVariableUpdate.getValue());
             }
             else {
                Integer currentRevision = historicVariableUpdate.getRevision();
                Integer previousRevision = versionMap.get(historicVariableUpdate.getVariableName());
                if(currentRevision > previousRevision) {
                   versionMap.put(historicVariableUpdate.getVariableName(), currentRevision);
                   variableMap.put(historicVariableUpdate.getVariableName(), historicVariableUpdate.getValue());
                }
             }
          }
       }
       
       for (String name : variableMap.keySet()) {
          result.addVariable(createRestVariable(securedResource, name, variableMap.get(name),
            RestVariableScope.LOCAL, processInstance.getId(), VARIABLE_PROCESS, false));
        }
    }
    else {
       //Process not complete. Get runtime variables.
       result.setCompleted(false);
       Map<String, Object> variableMap = runtimeService.getVariables(processInstance.getId());
       for (String name : variableMap.keySet()) {
          result.addVariable(createRestVariable(securedResource, name, variableMap.get(name),
            RestVariableScope.LOCAL, processInstance.getId(), VARIABLE_PROCESS, false));
        }
    }

(Note that I also added a boolean member variable to "ProcessInstanceResponse" to indicate whether a process instance had been completed or not.)

Perhaps I have something in the application misconfigured, and that is what is causing processInstance.getProcessVariables() call to return an empty set of variables? If so, please let me know. If not, maybe the code above will prove helpful to someone out there.
26 REPLIES 26

trademak
Star Contributor
Star Contributor
Hi Ryan,

Good to see you back on the forum 😉
Variables are not returned when creating a process instance, similar to how it works in the Java API.
The variables list is only filled when you query on process instances with the includeVariables option.
To get the variables an additional REST call is required.

Best regards,

ryanj1
Champ in-the-making
Champ in-the-making
And I'm happy to be back. Smiley Happy

If I'm understanding you correctly, you're basically saying that the product - in its out-of-the-box configuration - currently doesn't provide the ability to initiate a process and retrieve the current values of all variables when the process enters a wait state. Of course, that is consistent with the manner in which most (or all) BPM tools are currently designed and implemented. With that said, the pattern I'm describing is a legitimate pattern that customers may need their BPM tools to support. (In fact, one of the issues I encountered on a recent consulting engagement - where the customer was looking to select a BPM tool - was that none of the tools supported that pattern.) As a result, my thought is that it might be nice for Activiti to add a REST resource that would provide that ability.

Of course, I'd be willing to contribute that simple addition to the project if you agree that it would be helpful.

trademak
Star Contributor
Star Contributor
Hi Ryan,

Yes that's correct. I can understand that it's sometimes helpful to get back the variables directly in the response. If you are willing to add an option to the existing "create process instance" REST service that would be great.

Thanks,

ryanj1
Champ in-the-making
Champ in-the-making
Tijs,

Sorry for the delayed response. My current client - actually an Activiti client Smiley Happy - has had me working hard over the past couple of weeks. (It's been fun, though.)

I'd be happy to add an option to the existing "create process instance" REST service. To do so, I would have to modify three source files:

1) org.activiti.rest.service.api.runtime.process.ProcessInstanceCreateRequest (I would need to add the additional boolean variable here to indicate whether to return variables.)
2) org.activiti.rest.service.api.runtime.process.ProcessInstanceResponse (This isn't technically required for this change, but a nice, complementary feature is a flag in the output noting whether the process instance has been completed or not. That would be added herein.)
3) org.activiti.rest.service.api.RestResponseFactory (This is where the bulk of the code would be. I would use the code cited earlier within this thread.)

I assume you would want me to use the code for Activiti 5.15.1 to make these changes? (Though I suspect that none of these were changed from 5.15 to 5.15.1.) Let me know, and also let me know what timing constraints you have for the next release. Note that it shouldn't take me long to make these changes, primarily because I have all but the changes to ProcessInstanceCreateRequest already made (and tested) on my own instance. Smiley Happy

frederikherema1
Star Contributor
Star Contributor
Ryan,

Maybe good to have a pull-request for this, so we can take a better look at the suggested solution. I'm quite sure nothing changed in the code related to this feature. Including process-variables with a process-instance response is something that seems to be a common usecase, judging from the forum, so exposing this on the normal GET of a single instance whould also make sense (instead of only allowing this in the GET on the collection, as currently implemented).

ryanj1
Champ in-the-making
Champ in-the-making
Sounds like a plan. I'd be happy to just send along the code via email too if you'd like to have a look at it that way. And of course, if you have another recommendation on how to retrieve the variables that might be more efficient, I'd be happy to hear it.  

jbarrez
Star Contributor
Star Contributor
> Sounds like a plan. I'd be happy to just send along the code via email too if you'd like to have a look at it that way

Pull requests are easiest. Patches, emails also work 😉
Looking forward to it.


No changes in that area in the latest releases, so your explanation above should work.

ryanj1
Champ in-the-making
Champ in-the-making
I've created a pull request for my proposed modifications. Per Tijs comment earlier in this post, I added a flag ("returnVariables") that can be submitted in the request JSON to the POST runtime/process-instances endpoint to indicate whether variables should be returned or not. If it isn't specified or if it's set to false, the endpoint behaves in exactly the same manner as it does in Activiti today. Thus, this change shouldn't cause any issues for users who upgrade to a release in which these changes included and who use the endpoint in their environments today.

By the way, this is my first GitHub pull request, so if I messed something up, please let me know… Smiley Happy

-Ryan

ssun
Champ on-the-rise
Champ on-the-rise
Did not see this before my posts on the other thread. http://forums.activiti.org/content/list-process-instances-rest-returns-empty-processvariables

So what said on the other thread about this already pulled into master and fixed in next version of 5.13 is not correct?

–Gordon