Complete Zeebe user tasks using the Zeebe client

JGeek: How to complete users tasks using zeebe client?

How can I accept user inputs through an rest api call and mark the user tasks of a bpmn workflow as complete?

I could do it using the RuntimeService & TaskService in C7 but I am stuck on how to do it with C8. I posted a https://forum.camunda.io/t/how-to-implement-a-spring-boot-rest-application-with-camunda-8/37902|question on the forum but since i didn’t get an answer on it for a few days I am posting it here to see if I can get unstuck quickly :slightly_smiling_face:

Thanks!

Manu Dittmar: Hi ! you could write a worker for type io.camunda.zeebe:userTask - same like with any other worker :slightly_smiling_face: when completing the job, you can also provide variables

Manu Dittmar: A job worker example: https://docs.camunda.io/docs/0.26/guides/setting-up-development-project/#create-a-job-worker

JGeek: Thanks @Manu Dittmar for a quick reply. I have two questions

  1. How do mention the type? From the camunda sample project I could see a service task worker registered with the below code. If I write io.camunda.zeebe:userTask as the type, where do I give the name of the user task?
@ZeebeWorker(type = "email", autoComplete = true)
public void sendEmail(final ActivatedJob job) {
  //code
}
2. If we were to do it this way there is no difference between a service task worker and user task worker? How do I accept user inputs which I was assuming doing it through rest apis.

Thanks

Manu Dittmar: @JGeek You could get the elementId (to map it to the bpmn element).

@ZeebeWorker(type = "io.camunda.zeebe:userTask")
public void handleJob(final JobClient client, final ActivatedJob job) {
  // Element Id
  System.out.println(job.getElementId());
  // get variables
  Map variables = job.getVariablesAsMap();
  // business logic
  // ...
  // complete the tasks
  client.newCompleteCommand(job.getKey())
      .variables(Map.of("newVariable","VariableFromClient"))
      .send()
      .join();
}

I wanted to show you that approach, as you mentioned it in the forum - but did you had a look at the GraphQL API of Tasklist? That would probably feel more natural to query for tasks + complete tasks

I can recommend following blogpost: https://camunda.com/blog/2022/05/getting-started-with-camunda-platform-8s-graphql-api/

Manu Dittmar: For Providing User Input, you could use Camunda Tasklist out-of-the-box or use the graphql api to complete a task and provide variables https://docs.camunda.io/docs/apis-clients/tasklist-api/mutations/complete-task/

JGeek: Thanks @Manu Dittmar for quick inputs. You mentioned 3 approaches

  1. Zeebeworker - from the code you shared it seems we will have to have a common method for all user tasks and then add a switch case for each user task based on the element id. Did I get that right?
  2. Tasklist - This is available out-of-the-box but we have our own UI forms designed that we want to integrate it camunda user tasks. Hence we cannot use tasklist
  3. GraphQL - I will explore this and go through the links you shared. A quick question - so zeebe engine has an in-build graphql server?
    Thanks

Manu Dittmar: Hi <@U03F69Y0V8A>
yes - all usertask jobs do have the same type.

the zeebe engine itself does not have a graphql api - but tasklist does, Also if you dont want to use the tasklist ui - it’s worth it to have a look at the api that tasklist provides. I recommend to have a look at the architecture of C8, to better understand how the components work: https://docs.camunda.io/docs/components/zeebe/technical-concepts/architecture/

JGeek: Yes I have been through this architecture page but it doesn’t mention that zeebe workflow engine/cluster runs a graphql api server inbuilt.

I plan to run a self-managed zeebe engine in production using k8s. Current I am running it locally using <https://github.com/camunda/camunda-platform/blob/main/docker-compose-core.yaml|this docker-compose file>

Manu Dittmar: yes because it is part of tasklist :slightly_smiling_face: https://docs.camunda.io/docs/components/tasklist/introduction/ But the docker compose also comes with tasklist so you are good to go and play around with it :smile:

JGeek: Oh ok. If its part of the tasklist then it cannot be used in production under the free license right?

if so, we can’t use graphql then

JGeek: Assuming that the only option left is to write a common Zeebe worker method for all user tasks, how do I call this method in the rest api that accepts user inputs?

skayliu: Hi @JGeek ,you can take a look this ,https://github.com/camunda-community-hub/zeebe-simple-tasklist

JGeek: I am going through this repository. Could you help me understanding <zeebe-simple-tasklist/TaskResource.java at 676ab696a8b52a9ed2c6fb9a22fb045b2b57d6a7 · camunda-community-hub/zeebe-simple-tasklist · GitHub rest api> exposed for completing a task?

The key accepted here as input is the jobKey. Job is generated by the zeebe workflow engine. How can the user or the FE code get to know the jobKey to be able to call this rest api?

Thanks.

skayliu: you’d look at ViewController.java for the method taskList or allTaskList,when the login user open a task,then get the key.

JGeek: Ok so just trying to understand the whole data flow

  1. The process is started using zeebeClient.newCreateInstanceCommand()
  2. Zeebe brokers execute tasks and the process blocks at the user task.
  3. This process blocking could be indefinite time till someone calls the ViewController api /views/my-tasks
  4. This api returns all the jobs assigned to the given user that are generated by the workflow engine for the active user tasks.
  5. A Job contains a key that is used to mark the task as complete so that the process continues.
    Is my understanding correct?

JGeek: @skayliu - I do not think the git repo that you shared - zeebe-simple-tasklist is relevant to the problem that I am trying to solve. I don’t see a solution that allows me to accept user inputs (through a rest api call) in a zeebe client and then mark it complete. If I missing something kindly let me know.

@zell - Do you have any inputs on this topic? I am stuck trying to find a solution to this question but hasn’t been able to for more than a week. I tried posting it on the forum too but no luck yet.

Thanks

JGeek: I came across <https://forum.camunda.io/t/how-to-complete-a-user-task-in-zeebe-client-of-version-1-1-0-stable/36560/4|this forum thread> that mentioned the same problem. It seems the only solution is the have a zeebe worker for user tasks too in C8 that can be marked complete through the client api.

Note: This post was generated by Slack Archivist from a conversation in the Camunda Platform 8 Slack, a source of valuable discussions on Camunda 8 (get an invite). Someone in the Slack thought this was worth sharing!

If this post answered a question for you, hit the Like button - we use that to assess which posts to put into docs.

Hi, I meet the same problem, only use zeebe but not tasklist.
I got one solution to want to discuss:
1, create a zeebe worker for user task, when receive just store into own database, then complete the worker.
2, add a message event after the worker.
3, after a user updates some info or calls some API, publish a message through zeebe client to continue the workflow.

don’t know whether can run like this.

sean

Hi @Sean_Y

Yes, you can. See here: How do I structure a system with Zeebe and RabbitMQ or other external system?

Josh