Difference between the Is the 'bpmn:process id' contained in XML supposed to be unique for each definition?

I have created a BPMN2.0 XML file using the modeller. While creating the workflow, I have provided a process-id of my choice, say “ABC”. In the XML file, the “bpmn:process id” is “ABC” as expected.

I have deployed it using Zebee (Java)'s newDeployResourceCommand() API. The deployment is successful and the result provides an unique numeric ID.

Then, I have copied the XML file and in the new file, have changed the “bpmn:process id” to “DEF” and left the rest of the file, unchanged. Then, I deploy this new file. This time too, the deployment is successful and the result provides another unique numeric ID.

The ‘operate’ console shows that there are two process definitions deployed and the ‘process id’ are correctly shown (exactly as in the XML file).

Does this mean, the ensuring the uniqueness of ‘bpmn:process id’ is the responsibility of the person who is modeling? In other words, if by mistake, the ‘bpmn id’ is copied across two completely separate workflow definition files, Camunda 8 will consider them to be the same workflow?

Please point out the gap in my understanding and make me wiser.

Hi @nsengupta, welcome to the forums! Yes, the process ID must be unique between processes. To be more specific, the uniqueness of each deployed process is the process ID + the version. This link to our docs shares a bit more info:

@nathan.loding Many thanks for a quick response.

I understand the point. So, for programmatic activation of a workflow using Zeebe, we deploy a process definition:

var deployed = zeebeClient
            .newDeployResourceCommand()
            .addResourceFile(some_definition_XML_file)
            .send()
            .join();

The deployed.getKey() returns a long random number. This is the same as deployed.getTenantId(). It is not clear, how should this particular value be used.

There is only one process in my case. I observe, that the deployed.getProcesses()[0].getBpmnProcessId() and deployed.getProcesses()[0].getProcessDefinitionKey are different.

  • getBpmnProcessId() returns the <bpmn:process id= value from the BPMN XML file.
  • getProcessDefinitionKey() returns another random number. If it is significant, then I presume its uniqueness is ensured by Zeebe engine.

How are these value supposed to be used?

As an example, in the following code snippet:

zeebeClient
            .newCreateInstanceCommand()
            .bpmnProcessId("XXXX") // which value is this?
            .latestVersion()  // or, a version of my choice
           .send()
           .joint();

The following Javadoc is a bit confusing because it does not elaborate what each field is meant to carry. My knowledge is limited and I need help.

@nsengupta - thanks for sharing those details. After reading your post I agree that the docs here are a bit confusing.

The processDefinitionKey is unique for each version of a process definition, while bpmnProcessId remains the same across different versions of the same process. In other words, the key is a unique identifier for the ID+Version. You can access/start the same process version using either the key or the ID+Version.

In your snippet that starts a new process instance, you are using the ID+Version, which, I believe, is our recommendation. The gRPC endpoint does support using the key if you’d like (docs) - the endpoint supports the key or the ID+Version.

I’m not sure why deploy.getKey() and getTenantId() are the same. Was it a coincidence for that one deployment, or are they always the same? The key should return the deployment key (which is different from the processDefinitionKey) and a tenant ID (see the gRPC definition here). The tenant ID is used for multi-tenancy.

Hopefully that helps clarify - let me know what other questions you have. I’d also love to hear any thoughts you have about improving the clarity of the docs on these topics! I can share you feedback with our documentation team (or you can open a PR yourself if you want, by clicking the “Edit this page” link at the bottom of any docs page).

@nathan.loding Thanks again, for a quick and detailed reply. Here’s what I have found out, armed with your explanation, the links to gRPC docs and a bit of exploration on my part.

sample-workflow

In the XML file (“./diagram_6.bpmn”), , the process-id tag is <bpmn:process id="process-payments-6-NS".
Given this workflow, the following code snippet

var zeebeDeploymentReport = zeebeClient
            .newDeployResourceCommand()
            .addResourceFile(wfToDeploy.wfDefinitionFilePath())
            .send()
            .join();

provides the following info.

  • The Deployment Key is Long value; in my case 2251799814356918. From the gRPC Protobuf definition, this is supposed to represent // the unique key identifying the deployment. Got it.
  • The Tenant ID is just <default>; no idea why! In a self-managed set up, where there is no other tenant, it should say something like ‘Are you lonesome?’ and may be, put a hand on my shoulder! :smiley:
  • The number of processes is 1. Perfect!

That single process carries more information, such as:

  • The bpmnProcessId (refer to the Javadoc in my earlier response) is as expected: process-payments-6-NS. No surprises! From the gRPC Protobuf definition, this is supposed to represent // the bpmn process ID, as parsed during deployment; together with the version forms a unique identifier for a specific process definition.

  • The resourceName is the name of the file: ./diagram_6.bpmn.

  • The version is 7. This is so, because I have been experimenting and thus, a number of versions have been created. Before executing the code shown above, I have meticulously removed the preceding 6 versions, using ‘operate’ web console.

  • The processDefinitionKey is Long value; in my case 2251799814326464.
    From the gRPC Protobuf definition, this is supposed to represent // the assigned key, which acts as a unique identifier for this process. Importantly, this value is not the same as the ‘Deployment Key’ above.
    [Note]: From your reply above, I understand that the ‘bpmnProcessId + version’ combo is equivalent to the ‘processDefinitionKey’.

  • The tenantdId is, well, <default>. I mean, why, Zeebe, why? Don’t you know me? :thinking:

With everything being set, the following code snippet, creates an instance of the workflow:

var zeebeCreatedInstanceReport = 
       zeebeClient
       .newCreateInstanceCommand()
       .processDefinitionKey(
           zeebeDeploymentReport
              .getProcesses().get(0)
              .getProcessDefinitionKey()
       )
//.bpmnProcessId(zeebeDeploymentReport.getProcesses().get(0).getBpmnProcessId())
// .latestVersion()
        .send()
        .join();

[Note]: Watch the commented two lines above.

The following info are available:

  • processDefnitionKey is 2251799814326464, the same as reported after the deployment. No surprise.
  • bpmnProcessID is process-payments-6-NS, the same as reported after the deployment. No surprise.
  • resourceName and version are the same as reported before, as well.
  • tenantID is, you guessed it, !
  • processInstanceKey is 2251799814356919. This is important, of course. From the gRPC Protobuf definition, this is supposed to represent // the unique identifier of the created process instance; to be used wherever a request needs a process instance key (e.g. CancelProcessInstanceRequest).

At this point, I have checked the state of Camunda 8 Workflow engine through ‘operate’ web console. Indeed, a workflow has been deployed and an instance of it, created and running.

Then, I run the following:

var z = zeebeClient
                 .newCancelInstanceCommand(
                         zeebeCreatedInstanceReport.getProcessInstanceKey()
                 )
                 .send()
                 .join();

The return value is an object, carrying no useful information. It is impossible to know, programmatically, if the cancellation has gone through or not. When I check at ‘operate’ web console, the state of the process instance is not always ‘cancelled’. It may be because of some delay, but it is not predictable from what I have seen so far.

Further, I have tried this:

var y = 
    zeebeClient
    .newDeleteResourceCommand(
    // Remember, that Key that was returned 
    // when the deployment was successful?
    zeebeDeploymentReport.getKey()) 
    .send()
    .join();

This throws as exception:

NOT_FOUND: Command 'DELETE' rejected with code 'NOT_FOUND': Expected to delete resource but no resource found with key `2251799814370438`

This is what gRPC Prortobuf definition says:

message DeleteResourceRequest {
// The key of the resource that should be deleted. This can either be the key
// of a process definition, the key of a decision requirements definition or the key of a form.
int64 resourceKey = 1;
}

So, it is not clear at all, of what use that key is (even though it is mentioned in the gRPC Protobuf description file)?

Out of curiosity, I have tried the following, because the name processDefinitionKey suggests that this may be appropriate:

var y =
     zeebeClient
     .newDeleteResourceCommand(
     // This is processDefinitionKey and *not* the processInstanceKey
       zeebeCreatedInstanceReport.getProcessDefinitionKey()
     )
     .send()
     .join();

The return value is an object, carrying no useful information. So, It is impossible to know, programmatically, if the deletion of the resource has gone through or not. When I check at ‘operate’ web console, the workflow deployed is still shown to be present!!

This is long, I know. I hope you will have the patience to read through it all. I have tried to give as much information as possible. I hope it is useful. Thanks for coaxing me. :smiling_face:

Please guide me, for the next steps.

Hey @nsengupta - my reply is quite short, but hopefully you find all the answers you need in it!

  • the default tenantID is <default> so it’s no surprise to see it there; no sarcasm allowed in the API spec! :joy:
  • you’ve got everything correct up until .newDeleteResourceCommand(zeebeDeploymentReport.getKey()) - that key is just a record of the deployment, not the resource; this would be the processDefinitionKey, as you found in the next snippet

It may be because of some delay, but it is not predictable from what I have seen so far.

I would suggest looking at Zeebe’s architecture and how exporters work. The supporting applications - Tasklist, Optimize, and Operate - all pull their data from a long-term cold data-store (by default, Elastic). Zeebe has to export that data, and there can be a delay depending on what else is happening within the cluster. It would be normal to see a short delay before changes are reflected in these applications. The typical delay should only be a few seconds, but depending on the size of the cluster and other concurrent operations, it could take longer.

As for not knowing whether the resource was successfully deleted or canceled with the Zeebe Client, that is great feedback! I’ll take this to the product team so they can look at making the client a bit more fluent and helpful.

Thank you, @nathan.loding . That is helpful.

If my little tongue-in-cheek comments about tenantId is offensive to some, I sincerely apologize. My intention was to make an otherwise dull and drab conversation, a bit lighter. :blush:

When you take it up to the product team, please also point out that some hint as to what purpose does that zeebeDeploymentReport.getKey() value serve, will be helpful. There must be a reason why it is being returned as a result of a call to an embedded library; otherwise, why will the product team even care to let the caller know of its presence?

Thank you for your time.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.