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
Data Object and Data Object Reference name vs ID #214
Comments
So it seems that the part of this issue is really the PythonScriptEngine that does not consider those data when they are put back into the workflow data dict. The following methods could be updated to add the workflow data? I'll let you check if this is wanted and the right way to implement. Else, I'll look into override this methods for myself. SpiffWorkflow/SpiffWorkflow/bpmn/PythonScriptEngine.py Lines 185 to 200 in 0fa2048
def evaluate(self, task, expression):
"""
Evaluate the given expression, within the context of the given task and
return the result.
"""
try:
if isinstance(expression, Operator):
# I am assuming that this takes care of some kind of XML
# expression judging from the contents of operators.py
return expression._matches(task)
else:
+ context_data = {**task.data, **task.workflow.data}
+ return self._evaluate(expression, context=context_data, task=task)
- return self._evaluate(expression, task.data, task=task)
except Exception as e:
raise WorkflowTaskExecException(task,
"Error evaluating expression "
"'%s', %s" % (expression, str(e))) Still left to see what is your idea/stance on the BPMN ID vs Name. |
There is a quick answer to your point about bpmn id -> spiff name and bpmn name -> spiff description. Spiff tasks have auto-generated ids, so we don't overwrite those and we use this mapping instead. I agree it is confusing, but it is the same across parsing of all bpmn elements, so we are not going to deviate from it because consistency is important too. I don't think there is an an easy fix for having to edit the XML. As you note, the camunda UI only gives you access to the reference, not the underlying data object, but it's the underlying object that we really care about. We're working on our own version on bpmn js (repo here https://github.com/sartography/bpmn-js-spiffworkflow) that handles data objects a little better (we expose the underlying objects and allow multiple references to point to the same object, which camunda does not let you do -- every time you create a data object reference it generates a new object). You might take a look at that and see if it's useful to you. We should be adding the requested workflow data into the task data automatically -- you should not have to do it yourself. This may be a bug and I will look into it. |
Thank you very much. I understand that it's your internal tool, so I'll bend to your mapping. No issues there then. As for the modeler, it took me a while to understand how to set it (I was thinking it was a React component at first!), but it seems to be working as expected with the DataObjects. My only issue is that I needed a "portable" modeler desktop software, so I would have liked to get a plugin for the desktop version. But that'll do for now; I might just either make the modeler into my React app or into the desktop plugin one day. One last thing, if you can help me figure it out (I am new to this whole BPMN thing and it's driving me crazy this week!), is there a way to define in the DataObject attributes what is the underlying python or typescript class? Like, I want this DataObject "decision" to be of type "string" or "integer" or "MyCustomClass" or "MyCustomEnum", so that both my backend and frontend knows that to expect and provide as input/output. I was thinking using DataObjectReference, but clearly this is not it! Thanks again! :) |
I believe the BPMN way of setting types would be to use an Also, the issue with the process-level variables not being recognized by the gateways is definitely a bug, so I wanted to confirm that. I was initially going to include your proposed fix, but then I asked myself "if there is a conflict between a task and process variable, which takes precedence?". One solution would be to give one or the other precedence. Another would be to add process variables as a dictionary with a standard name, and they could be distinguish by using eg But we will definitely include some fix that allows process variables to used by gateways (and other elements that rely on |
I also should have mentioned that we use the updated bpmn js in a react app (repo here https://github.com/sartography/spiffworkflow-frontend). Also in development, but maybe potentially useful to you. |
Thank you for your answer on this! I'll check on Tuesday when I am back on my project.
As a dev user, my intuitive solution would be to have each of the task variables and process variables inside a dictionary on their own ( However, my perspective as a BPMN user (with I don't have deep understanding) would be to keep it as simple as possible. I would put the burden on SpiffWorkflow to figure out which variable to take in the However, to deal with collisions, I would let the default From there, I see two options.
DictionaryThe current object would look like this if we put both in the same dictionary. Duplicate key are not possible, so the {
[... task other properties]
'data':
{
'Task_DataObject': 'value1',
'Process_DataObject': 'value2',
'TaskProcess_DataObject': 'value3',
'TaskProcess_DataObject': 'value4',
}
} My idea would be that the new object would look like this. So, no collision possible. {
[... task other properties]
'process_data':
{
'Process_DataObject': 'value2',
'TaskProcess_DataObject': 'value4',
},
'task_data':
{
'Task_DataObject': 'value1',
'TaskProcess_DataObject': 'value3',
},
} PythonScriptEngineIn here, we send a context that has the symmetric difference of both set (basicaly, keeping only variables that are not in both sets), the process_data and task_data dictionary under their own key of the context and use that dictionary to evaluate the expression. So, it should cover both implicit without collision and explicit call out of variables by the BPMN user. (a note should be given to the BPMN user that If the expression cannot be evaluated because the variable is not in the merged dict, instead of just throwing that to the user, a check should be made if the variable name is in the task data dictionary. If yes, that mean it is a data collision and we send this to a new method So, this is my long answer... brain is now going to sleep! I'll check on this on tuesday. |
Trying to keep things simple is definitely one of our priorities. We decided early on that sticking with task data was simpler than process data but we really wanted to be able to define inputs to subprocesses, so that was the main impetus behind adding data object support. A secondary concern was the ability to temporarily remove objects from the task data, in order to not have to copy them over and over again if they are not actively being used. We expected people to just draw arrows from data objects to the bpmn elements that use them in the case where a task needs access to the process data, so I was initially going to suggest drawing an arrow to the gateway or sequence flow that uses the data object, but I discovered that camunda doesn't let you do that. We're going to update bmn.js to allow this, as the bpmn spec indicates that this is perfectly valid. An alternative solution to your issue would be to leave the data object data in the task until you're done manipulating it and store it in the data object at that point. Implementing a custom script engine is an interesting idea and this is what I'd advise you to do if our solutions don't meet your needs. |
FWIW: I loved the idea of having a Data Object connected to a Gateway, and I put a few hours into making that possible this morning, only to realize that it is prohibited by the BPMN 2.0 schema, and so we can't model it in a valid diagram. I did some digging in the official specification and found some details on page 345. It sais " The data used for Gateway Conditions MUST have been in a Message that was sent prior to (upstream from) the One of the really great features of Data Objects is the ability to dictate what tasks can access that data, and which cannot. But that isn't in any way connected to the BPMN standard. So I am inclined to say that we should provide a way to reference process level variables (Data Objects) from within a Gateway using some key as @sharky98 proposed, and making such access possible and standard across the Execution Engine. At this point, I, for one, would be willing to accept such a pull request. |
Hello,
I am facing multiple issues regarding the data object and its reference. I am using either Camunda or Modelio to model my BPMN, which is a simple user task that output a decision DataObject and an exclusive gate that either go to the end or redo the user task based on the Decision DataObject.
I checked both examples (cli and ducks) and tests, but everything is based on Camunda Forms, which isn't a route I want to go. Keeping with BPMN only, I was thinking of using DataObject as a trigger to my python app that something must be provided to the process.
I currently use a standalone script based on your CLI example (hardcoded the BPMN files, forced the debug and changed the user task to set the value of the data output) to figure out how to work with BPMN and your library. You'll find below relevant part of codes. To summarize, here my issues.
Thanks for reading me, and hopefully you'll have some idea how to sort this out!
BTW, I am using a editable from source installation of the package, since the latest released version does not have support for those data object.
Here is where you use the ID as the name.
SpiffWorkflow/SpiffWorkflow/bpmn/specs/BpmnProcessSpec.py
Lines 73 to 82 in 0fa2048
Here is where you use the same ID to check if it exist as a data object.
SpiffWorkflow/SpiffWorkflow/bpmn/parser/node_parser.py
Lines 30 to 48 in 0fa2048
Here is how I changed the
complete_user_task(task)
. It is hardcoded for now, assuming only one output requested.Here is the error I got that the name is not defined.
Here my BPMN process from Camunda. It will fail to evaluate
decision="redo"
because it is stored asDataObject_17prm6c
.Here the same process as generated by Modelio
The text was updated successfully, but these errors were encountered: