From a5a10a0cff79d77c23a6d21e0f50f3ab28dcc727 Mon Sep 17 00:00:00 2001 From: christinaausley <84338309+christinaausley@users.noreply.github.com> Date: Fri, 6 Dec 2024 16:29:45 -0500 Subject: [PATCH 1/9] migration support for zeebe user tasks (#4573) * migration support for zeebe user tasks * grammatical tweaks * begin updating migration guide * update imports * typo * update to c8 api * fix broken links * formatted table * Update resource-planning.md * rebase * rebase * update based on new changes * backport * adjust sidebars * adjust sidebars * revert some 8.5 changes * revert 8.5 changes * adjust link * adjust sidebar * revert 8.5 sidebar * update 8.5 sidebar * remove get user task from 8.6 * Update 03-task-application-architecture.md * Update the migration guide to Zeebe (Camunda) user tasks * Update the documentation about user tasks * Rename "Zeebe user task" to "Camunda user task" * Note that embedded forms are supported only by Job worked-based user tasks * revert a few changes in next * revert user task changes * backport a few changes * Update migrate-to-zeebe-user-tasks.md * resolve build errors --------- Co-authored-by: Jonathan Lukas Co-authored-by: volodymyr-melnykc --- .../02-user-task-lifecycle.md | 2 +- .../03-task-application-architecture.md | 12 +- .../migrate-to-zeebe-user-tasks.md | 187 +++++++++-------- .../assets/img/api-architecture.png | Bin 65054 -> 0 bytes .../tasklist-api-rest/sidebar-schema.js | 1 - .../specifications/assign-task.api.mdx | 2 +- .../specifications/complete-task.api.mdx | 2 +- .../specifications/get-task-by-id.api.mdx | 2 +- .../specifications/search-tasks.api.mdx | 2 +- .../specifications/unassign-task.api.mdx | 2 +- docs/apis-tools/zeebe-api-rest/tutorial.md | 2 +- .../concepts/process-instance-migration.md | 2 +- .../modeler/bpmn/user-tasks/user-tasks.md | 2 +- .../advanced-modeling/form-linking.md | 4 + docs/reference/release-notes/850.md | 2 +- optimize_sidebars.js | 5 - .../version-3.14.0-sidebars.json | 5 - sidebars.js | 1 + static/.htaccess | 5 + .../migrate-to-zeebe-user-tasks.md | 2 +- .../tasklist-api-rest-overview.md | 6 + .../03-task-application-architecture.md | 12 +- .../migrate-to-zeebe-user-tasks.md | 190 ++++++------------ .../tasklist-api-rest/sidebar-schema.js | 1 - .../tasklist-api-rest-overview.md | 6 + .../apis-tools/zeebe-api-rest/tutorial.md | 2 +- .../modeler/bpmn/user-tasks/user-tasks.md | 2 +- .../advanced-modeling/form-linking.md | 4 + .../reference/release-notes/850.md | 2 +- versioned_sidebars/version-8.6-sidebars.json | 9 +- 30 files changed, 214 insertions(+), 262 deletions(-) rename docs/apis-tools/{tasklist-api-rest => migration-manuals}/migrate-to-zeebe-user-tasks.md (61%) delete mode 100644 docs/apis-tools/tasklist-api-rest/assets/img/api-architecture.png rename versioned_docs/version-8.6/apis-tools/{tasklist-api-rest => migration-manuals}/migrate-to-zeebe-user-tasks.md (57%) diff --git a/docs/apis-tools/frontend-development/01-task-applications/02-user-task-lifecycle.md b/docs/apis-tools/frontend-development/01-task-applications/02-user-task-lifecycle.md index cabf0ea6826..85fdc6ea1eb 100644 --- a/docs/apis-tools/frontend-development/01-task-applications/02-user-task-lifecycle.md +++ b/docs/apis-tools/frontend-development/01-task-applications/02-user-task-lifecycle.md @@ -78,7 +78,7 @@ Make sure that you create your own validation logic that matches your use case. ## Implement the life cycle with the task API -To implement task life cycle operations with the Zeebe task API, call the respective endpoints: +To implement task life cycle operations with the task API, call the respective endpoints: - [`POST /user-tasks/:taskKey/assignment`](/apis-tools/zeebe-api-rest/specifications/assign-a-user-task.api.mdx) or [`DELETE /user-tasks/:taskKey/assignee`](/apis-tools/zeebe-api-rest/specifications/unassign-a-user-task.api.mdx) to change task assignment. - [`PATCH /user-tasks/:taskKey`](/apis-tools/zeebe-api-rest/specifications/update-a-user-task.api.mdx) to update a task. diff --git a/docs/apis-tools/frontend-development/01-task-applications/03-task-application-architecture.md b/docs/apis-tools/frontend-development/01-task-applications/03-task-application-architecture.md index 50dfb21ef17..b0027b95827 100644 --- a/docs/apis-tools/frontend-development/01-task-applications/03-task-application-architecture.md +++ b/docs/apis-tools/frontend-development/01-task-applications/03-task-application-architecture.md @@ -6,10 +6,10 @@ description: "Understand and decide on the architecture of your task application A typical task application architecture consists of a task application frontend, a backend-for-frontend, and one or more data sources or services that contain business data relevant for the application users to perform their work. The backend implements Camunda Zeebe and Tasklist clients to retrieve and interact with tasks via Camunda APIs. For historical process instance data, Operate is also required. -Depending on the user task implementation type (job-based vs Zeebe user task) you use in your processes, you need to run either the Tasklist or Zeebe client to run operations on task. Task, form, and variable retrieval happens via the Tasklist API. Learn more about the differences of the task implementation types in the [migration guide for Zeebe user tasks](/apis-tools/tasklist-api-rest/migrate-to-zeebe-user-tasks.md). +Depending on the user task implementation type (job worker-based vs Zeebe user task) you use in your processes, you need to run either the Tasklist or Zeebe client to run operations on task. Task, form, and variable retrieval happens via the API. Learn more about the differences of the task implementation types in the [migration guide for Zeebe user tasks](/apis-tools/migration-manuals/migrate-to-zeebe-user-tasks.md). :::tip -Starting a completely new project? Use only Zeebe user tasks to simplify your implementation. +Starting a new project? Use Zeebe user tasks to simplify your implementation. ::: Click on any element of this diagram to jump to the documentation page for the respective component: @@ -72,14 +72,14 @@ style Tasklist stroke:#10c95d,color:#000 click Forms "../../forms/introduction-to-forms" click Rest "../../../tasklist-api-rest/tasklist-api-rest-overview" -click Job "../../../tasklist-api-rest/migrate-to-zeebe-user-tasks" -click ZeebeTasks "../../../tasklist-api-rest/migrate-to-zeebe-user-tasks" +click Job "../../../migration-manuals/migrate-to-zeebe-user-tasks" +click ZeebeTasks "../../../migration-manuals/migrate-to-zeebe-user-tasks" click ZeebeRest "../../../zeebe-api-rest/zeebe-api-rest-overview" ``` Follow these resources to learn more about the individual components: -- Familiarize yourself with the [Tasklist API](/apis-tools/tasklist-api-rest/tasklist-api-rest-overview.md) for task, variable, and form retrieval, and to run operations on job-based user tasks. -- Learn how to use the [Zeebe API](/apis-tools/zeebe-api-rest/zeebe-api-rest-overview.md) to run operations on Zeebe-based user tasks. +- Learn how to use the [Camunda 8 API](/apis-tools/camunda-api-rest/specifications/assign-user-task.api.mdx) for task, variable, and form retrieval, and to run operations on Zeebe user tasks. +- Familiarize yourself with the [Tasklist API](/apis-tools/tasklist-api-rest/tasklist-api-rest-overview.md) to run operations on job worker-based user tasks. - Understand how to design, embed, and customize [forms](/apis-tools/frontend-development/03-forms/01-introduction-to-forms.md). - Understand how this architecture fits into the overall Camunda architecture with the [Java greenfield stack](/components/best-practices/architecture/deciding-about-your-stack.md). diff --git a/docs/apis-tools/tasklist-api-rest/migrate-to-zeebe-user-tasks.md b/docs/apis-tools/migration-manuals/migrate-to-zeebe-user-tasks.md similarity index 61% rename from docs/apis-tools/tasklist-api-rest/migrate-to-zeebe-user-tasks.md rename to docs/apis-tools/migration-manuals/migrate-to-zeebe-user-tasks.md index b4f17bacb49..4b6a81d4d47 100644 --- a/docs/apis-tools/tasklist-api-rest/migrate-to-zeebe-user-tasks.md +++ b/docs/apis-tools/migration-manuals/migrate-to-zeebe-user-tasks.md @@ -1,32 +1,32 @@ --- id: migrate-to-zeebe-user-tasks title: Migrate to Zeebe user tasks -description: "Learn how to migrate job worker-based user tasks to Zeebe-based tasks." +description: "Learn how to migrate job worker-based user tasks to Zeebe user tasks." --- import DocCardList from '@theme/DocCardList'; import FormViewer from "@site/src/mdx/FormViewer"; -import YesItem from "./assets/react-components/YesItem"; -import NoItem from "./assets/react-components/NoItem"; -import TableTextSmall from "./assets/react-components/TableTextSmall"; -import userTaskMigrationDecisionHelperForm from "./assets/forms/userTaskMigrationDecisionHelperForm.js"; -import "./assets/css/condensedTable.module.css"; -import styles from "./assets/css/cleanImages.module.css"; -import APIArchitectureImg from './assets/img/api-architecture.png'; -import ZeebeTaskSelectionImg from './assets/img/zeebe-user-task-selection.png'; - -Camunda 8.5 introduces a new [user task](/components/modeler/bpmn/user-tasks/user-tasks.md) implementation type: Zeebe user tasks. -Zeebe user tasks have several benefits, including: +import YesItem from "../tasklist-api-rest/assets/react-components/YesItem"; +import NoItem from "../tasklist-api-rest/assets/react-components/NoItem"; +import TableTextSmall from "../tasklist-api-rest/assets/react-components/TableTextSmall"; +import userTaskMigrationDecisionHelperForm from "../tasklist-api-rest/assets/forms/userTaskMigrationDecisionHelperForm.js"; +import "../tasklist-api-rest/assets/css/condensedTable.module.css"; +import styles from "../tasklist-api-rest/assets/css/cleanImages.module.css"; +import ZeebeTaskSelectionImg from '../tasklist-api-rest/assets/img/zeebe-user-task-selection.png'; + +Camunda 8.5 introduced a new [user task](/components/modeler/bpmn/user-tasks/user-tasks.md) implementation type: Zeebe user tasks. + +Zeebe user tasks have several benefits compared to job worked-based user tasks. It includes: - Running directly on the automation engine for high performance. - Removing dependencies and round trips to Tasklist. -- A more powerful API that supports the full task lifecycle. +- A powerful API that supports the full task lifecycle. In this guide, you will learn: - Under which circumstances and when you should migrate. - How to estimate the impact on a project. -- The steps you need to take for a successful migration without interrupting your operations. +- Steps you need to take for a successful migration without interrupting your operations. ## Decide on your migration path @@ -34,17 +34,6 @@ Zeebe user tasks require migration of the user tasks in both your diagrams and t With this in mind, you can migrate at your own pace. If you should migrate now or later, and what is required to migrate depends on your current setup and future plans. -Use the following decision helper questionnaire to figure out what's right for you: - - - ### Task type differences Learn the differences between both task types and make an informed decision, and understand the new capabilities of Zeebe user tasks. Refer to this table for important high-level differences of the two task types: @@ -58,7 +47,7 @@ Learn the differences between both task types and make an informed decision, and
Zeebe user tasks
- Recommended for new projects + Recommended for existing and new projects @@ -91,11 +80,11 @@ Learn the differences between both task types and make an informed decision, and
Partially
Queries, GET tasks, forms, variables - ℹ Currently, you must use Zeebe and Tasklist APIs to use Zeebe user tasks + ℹ Currently, you must use the Camunda 8 and Tasklist APIs to use Zeebe user tasks - Supports Zeebe API + Supports Camunda 8 API @@ -123,7 +112,6 @@ Learn the differences between both task types and make an informed decision, and - Task listeners will be introduced in a future release @@ -146,10 +134,9 @@ Learn the differences between both task types and make an informed decision, and Recommendations You can continue to use this task type on existing projects when you have a custom task application running on it and do not require any of the above features. - Refer to the decision helper above for a tailored recommendation. - Use this task type on any new projects when you run Tasklist. + Recommended for existing and new projects when you run Tasklist. Migrate existing projects and task applications/clients to this task type when you require one of the features above, or the following use cases:
    @@ -161,12 +148,11 @@ Learn the differences between both task types and make an informed decision, and
  • Enrich tasks with business data
- Refer to the decision helper above for a tailored recommendation. -## Switch the implementation type of your user tasks +## Switch the implementation type of user tasks We recommend you migrate process-by-process, allowing you to thoroughly test the processes in your test environments or via your [CI/CD](/guides/devops-lifecycle/integrate-web-modeler-in-ci-cd.md). To do this, take the following steps: @@ -181,176 +167,183 @@ We recommend you migrate process-by-process, allowing you to thoroughly test the Repeat these steps for all user tasks in the process. Then, deploy the process to your development cluster and test it by running the process and ensuring your custom task applications work. -## Use the new Zeebe Task API +## Use Camunda 8 API :::note The Tasklist REST API is not deprecated, and you still need it for queries on both task types. ::: -Operations on Zeebe user tasks which modify the task state have to be performed using the new Zeebe REST API. However, queries and adjacent operations still require the Tasklist REST API. The following table provides a breakdown of which operations are supported in which API, and for which user tasks. +The following table provides a breakdown of which operations are supported in which API, and for which user tasks. - + + + + + + - - - + + + - - - + + + - - + + - - - + + + - - + + - - + + - + - - - + + +
Operation Tasklist APIZeebe Task API (8.5)Camunda 8 API
Deprecated on 8.7Supported from 8.6+
Query tasks All types← Use Tasklist APIQuery user task Job worker-based user tasks Zeebe user tasks
Get task All types← Use Tasklist APIGet user task Job worker-based user tasks Zeebe user tasks
Retrieve task variables All types← Use Tasklist API Job worker-based user tasks Zeebe user tasks
Get task form All types← Use Tasklist APIGet user task form Job worker-based user tasks Zeebe user tasks
Change task assignment Job worker-based tasks Zeebe tasks Job worker-based user tasks Zeebe user tasks
Complete task Job worker-based tasks Zeebe tasks Job worker-based user tasks Zeebe user tasks
Update task - Zeebe tasks Zeebe user tasks
Safe and retrieve draft variables All types← Use Tasklist APISave and retrieve draft variables Job worker-based user tasks -
-You can also operate both task types at the same time in the same application utilizing both APIs. We recommend this for a smooth migration, but you should eventually update all processes to use the new task type to use all benefits. The following image illustrates how to route API calls to the respective APIs: - -Task API Architecture - -The major changes are: - -- Create and maintain new, additional secrets for the Zeebe REST API. -- Call dedicated endpoints on separate components (Zeebe vs. Tasklist) for all state modifications on tasks for the respective task types. -- Manage new request/response objects. - The following table outlines the respective endpoints. Click the endpoints to follow to the API documentation and inspect the differences in the request and response objects. - + - + - + - + - + + - - + - + - + - +
Operation Tasklist APIZeebe Task API (8.5)Camunda 8 API
Query tasksQuery user tasks - + POST /tasks/search ← Use Tasklist API + + POST /user-tasks/search + +
Get taskGet user task - + GET /tasks/:taskId ← Use Tasklist API + + GET /user-tasks/:userTaskKey + +
Retrieve task variables - + GET /variables/:variableId -
- +
+ POST /tasks/:taskId/variables/search ← Use Tasklist API
Get task form - + GET /forms/:formId ← Use Tasklist API + + GET /user-tasks/:userTaskKey/form + +
Assign a task - + PATCH /tasks/:taskId/assign - - POST /user-tasks/:taskKey/assignment + + POST /user-tasks/:userTaskKey/assignment
Unassign a task - + PATCH /tasks/:taskId/unassign - - DELETE /user-tasks/:taskKey/assignee + + DELETE /user-tasks/:userTaskKey/assignee
Complete task - + PATCH /tasks/:taskId/complete - - POST /user-tasks/:taskKey/completion + + POST /user-tasks/:userTaskKey/completion
Update task-- - - PATCH /user-tasks/:taskKey + + PATCH /user-tasks/:userTaskKey
Safe and retrieve draft variablesSave and retrieve draft variables - + POST /tasks/:taskId/variables ← Use Tasklist API-
@@ -373,9 +366,9 @@ docId:"apis-tools/tasklist-api-rest/tasklist-api-rest-overview" }, { type:"link", -href:"/docs/next/apis-tools/zeebe-api-rest/zeebe-api-rest-overview/", -label: "Zeebe API (REST)", -docId:"apis-tools/zeebe-api-rest/zeebe-api-rest-overview" +href:"/docs/next/apis-tools/camunda-api-rest/camunda-api-rest-overview/", +label: "Camunda 8 API (REST)", +docId:"apis-tools/camunda-api-rest/camunda-api-rest-overview" } ]}/> @@ -383,6 +376,6 @@ docId:"apis-tools/zeebe-api-rest/zeebe-api-rest-overview" If your task application does not work properly after migration, check the following: -- **The endpoints return specific error messages when you run them on the wrong task type**: Ensure to call the right endpoint for the right task type, c.f. above [table](#use-the-new-zeebe-task-api). +- **The endpoints return specific error messages when you run them on the wrong task type**: Ensure to call the right endpoint for the right task type, c.f. above [table](#use-the-new-camunda-8-api). - **Forms do not appear**: Ensure you have extracted embedded forms, if any, and [transformed them into linked forms](/components/modeler/bpmn/user-tasks/user-tasks.md#camunda-form-linked), before you change the task type implementation. - **Task update operation does not work**: The update operation is only available to Zeebe user tasks. diff --git a/docs/apis-tools/tasklist-api-rest/assets/img/api-architecture.png b/docs/apis-tools/tasklist-api-rest/assets/img/api-architecture.png deleted file mode 100644 index 93cf8ef7c8f2340c6a03a272fd9423a0c284df74..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65054 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%0DVa;oa^68=}?4Anz_Pw2=Hdd)i+kZed~5WL2~H0 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 EAJ?<2?f?J) diff --git a/docs/apis-tools/tasklist-api-rest/sidebar-schema.js b/docs/apis-tools/tasklist-api-rest/sidebar-schema.js index 517c97c4df8..ebb41a15e74 100644 --- a/docs/apis-tools/tasklist-api-rest/sidebar-schema.js +++ b/docs/apis-tools/tasklist-api-rest/sidebar-schema.js @@ -7,6 +7,5 @@ module.exports = { { Specifications: require("./specifications/sidebar.js"), }, - "apis-tools/tasklist-api-rest/migrate-to-zeebe-user-tasks", ], }; diff --git a/docs/apis-tools/tasklist-api-rest/specifications/assign-task.api.mdx b/docs/apis-tools/tasklist-api-rest/specifications/assign-task.api.mdx index 14546a99a99..e15045dcb79 100644 --- a/docs/apis-tools/tasklist-api-rest/specifications/assign-task.api.mdx +++ b/docs/apis-tools/tasklist-api-rest/specifications/assign-task.api.mdx @@ -44,7 +44,7 @@ When using REST API with JWT authentication token following request body paramet On success returned. -
Schema
+
Schema
An error is returned when the task is not active (not in the CREATED state).
An error is returned when task was already assigned, except the case when JWT authentication token used and `allowOverrideAssignment = true`. diff --git a/docs/apis-tools/tasklist-api-rest/specifications/complete-task.api.mdx b/docs/apis-tools/tasklist-api-rest/specifications/complete-task.api.mdx index 1f4e3b31ea8..a2205914bde 100644 --- a/docs/apis-tools/tasklist-api-rest/specifications/complete-task.api.mdx +++ b/docs/apis-tools/tasklist-api-rest/specifications/complete-task.api.mdx @@ -44,7 +44,7 @@ Variables to update or add to task during the task completion On success returned. -
Schema
+
Schema
An error is returned when the task is not active (not in the CREATED state).
An error is returned if the task was not claimed (assigned) before.
An error is returned if the task is not assigned to the current user. diff --git a/docs/apis-tools/tasklist-api-rest/specifications/get-task-by-id.api.mdx b/docs/apis-tools/tasklist-api-rest/specifications/get-task-by-id.api.mdx index c9ba57ae4b2..ca8de33aad9 100644 --- a/docs/apis-tools/tasklist-api-rest/specifications/get-task-by-id.api.mdx +++ b/docs/apis-tools/tasklist-api-rest/specifications/get-task-by-id.api.mdx @@ -37,7 +37,7 @@ Get one task by id. Returns task or error when task does not exist. On success returned. -
Schema
+
Schema
User has no permission to access the task (Self-managed only). diff --git a/docs/apis-tools/tasklist-api-rest/specifications/search-tasks.api.mdx b/docs/apis-tools/tasklist-api-rest/specifications/search-tasks.api.mdx index b4d862e180d..e8e2b223ace 100644 --- a/docs/apis-tools/tasklist-api-rest/specifications/search-tasks.api.mdx +++ b/docs/apis-tools/tasklist-api-rest/specifications/search-tasks.api.mdx @@ -69,7 +69,7 @@ An array of the task's variables. Only variables specified in `TaskSearchRequest The draft value of the variable. -
  • ]
  • ]
  • +
  • ]
  • ]
  • An error is returned when more than one search parameters among `[searchAfter, searchAfterOrEqual, searchBefore, searchBeforeOrEqual]` are present in request diff --git a/docs/apis-tools/tasklist-api-rest/specifications/unassign-task.api.mdx b/docs/apis-tools/tasklist-api-rest/specifications/unassign-task.api.mdx index 2ecc8512e03..2e474e4b709 100644 --- a/docs/apis-tools/tasklist-api-rest/specifications/unassign-task.api.mdx +++ b/docs/apis-tools/tasklist-api-rest/specifications/unassign-task.api.mdx @@ -40,7 +40,7 @@ Unassign a task with `taskId`. Returns the task. On success returned. -
    Schema
    +
    Schema
    An error is returned when the task is not active (not in the CREATED state).
    An error is returned if the task was not claimed (assigned) before. diff --git a/docs/apis-tools/zeebe-api-rest/tutorial.md b/docs/apis-tools/zeebe-api-rest/tutorial.md index ec299cbe3a6..2bb1795037a 100644 --- a/docs/apis-tools/zeebe-api-rest/tutorial.md +++ b/docs/apis-tools/zeebe-api-rest/tutorial.md @@ -41,7 +41,7 @@ In this tutorial, we will execute arguments to assign and unassign a user to and ## Assign a Zeebe user task (POST) :::note -In this tutorial, you will capture a **Zeebe user task** ID to assign and unassign users in this API. Camunda 8.5 introduced this new [user task](/components/modeler/bpmn/user-tasks/user-tasks.md) implementation type, and these Zeebe user tasks are different from job worker-based user tasks. See more details on task type differences in the [migrating to Zeebe user tasks documentation](/apis-tools/tasklist-api-rest/migrate-to-zeebe-user-tasks.md#task-type-differences). +In this tutorial, you will capture a **Zeebe user task** ID to assign and unassign users in this API. Camunda 8.5 introduced this new [user task](/components/modeler/bpmn/user-tasks/user-tasks.md) implementation type, and these Zeebe user tasks are different from job worker-based user tasks. See more details on task type differences in the [migrating to Zeebe user tasks documentation](/apis-tools/migration-manuals/migrate-to-zeebe-user-tasks.md#task-type-differences). ::: First, let's script an API call to assign a Zeebe user task. diff --git a/docs/components/concepts/process-instance-migration.md b/docs/components/concepts/process-instance-migration.md index a48724ed25e..9e13aa0d367 100644 --- a/docs/components/concepts/process-instance-migration.md +++ b/docs/components/concepts/process-instance-migration.md @@ -370,7 +370,7 @@ The following limitations exist that may be supported in future versions: - An element that becomes nested in a newly added subprocess - An element that was nested in a subprocess is no longer nested in that subprocess - Mapping instructions cannot change the element type -- Mapping instructions cannot change the task implementation, e.g. from a job worker user task to a Zeebe User Task +- Mapping instructions cannot change the task implementation, e.g. from a job worker user task to a Zeebe user task - The process instance must be in a wait state, i.e. waiting for an event or external input like job completion. It may not be taking a sequence flow or triggering an event while migrating the instance A full overview of error codes can be found in the migration command [RPC](/apis-tools/zeebe-api/gateway-service.md#migrateprocessinstance-rpc) or [REST](/apis-tools/camunda-api-rest/specifications/migrate-process-instance.api.mdx). diff --git a/docs/components/modeler/bpmn/user-tasks/user-tasks.md b/docs/components/modeler/bpmn/user-tasks/user-tasks.md index 5212b2a3b2c..90a64a6191c 100644 --- a/docs/components/modeler/bpmn/user-tasks/user-tasks.md +++ b/docs/components/modeler/bpmn/user-tasks/user-tasks.md @@ -162,7 +162,7 @@ A user task does not have to be managed by Zeebe. Instead, you can also use job workers to implement a custom user task logic. Note that you will lose all the task lifecycle and state management features that Zeebe provides and will have to implement them yourself. Use job workers only in case you require a very specific implementation of user tasks that can't be implemented on top of Zeebe user tasks. :::info -If you started using Camunda 8 with version 8.4 or a lower version and upgraded to 8.5 or newer, your user tasks are probably implemented as job workers. Refer to the [migration guide](/apis-tools/tasklist-api-rest/migrate-to-zeebe-user-tasks.md) to find a detailed list of the differences between the task implementation types and learn how to migrate to Zeebe user tasks. +If you started using Camunda 8 with version 8.4 or a lower version and upgraded to 8.5 or newer, your user tasks are probably implemented as job workers. Refer to the [migration guide](/apis-tools/migration-manuals/migrate-to-zeebe-user-tasks.md) to find a detailed list of the differences between the task implementation types and learn how to migrate to Zeebe user tasks. ::: You can define a job worker implementation for a user task by removing its `zeebe:userTask` extension element. diff --git a/docs/components/modeler/web-modeler/advanced-modeling/form-linking.md b/docs/components/modeler/web-modeler/advanced-modeling/form-linking.md index c7cf43464fe..cf43c6b50c5 100644 --- a/docs/components/modeler/web-modeler/advanced-modeling/form-linking.md +++ b/docs/components/modeler/web-modeler/advanced-modeling/form-linking.md @@ -89,6 +89,10 @@ To correct any instances affected by this issue, we recommend the following step ### Camunda Form (embedded) +:::info +Embedded forms are supported only by job worker-based user tasks and are not available for the [Zeebe user task implementation type](/components/modeler/bpmn/user-tasks/user-tasks.md#user-task-implementation-types). +::: + When choosing **Camunda Form (embedded)** as type you have the option to directly paste the form's JSON schema into the **Form JSON configuration** field of the properties panel. The form will be embedded directly into the BPMN diagram's XML representation. diff --git a/docs/reference/release-notes/850.md b/docs/reference/release-notes/850.md index 43f3806758c..d514f55adca 100644 --- a/docs/reference/release-notes/850.md +++ b/docs/reference/release-notes/850.md @@ -108,7 +108,7 @@ The first iteration of this feature brings back existing features from Camunda 7 -The first step to offer an intuitive and consistent experience via a single, [unified Camunda 8 REST API](https://camunda.com/blog/2024/03/streamlining-camunda-apis-zeebe-rest-api/) is to provide the Zeebe REST API. With this release, developers can use the Zeebe REST API to manage [Zeebe user tasks](/apis-tools/tasklist-api-rest/migrate-to-zeebe-user-tasks.md), enabling immediate task state changes. The Zeebe REST API includes support for Identity authentication and multi-tenancy, ensuring parity to the Zeebe gRPC API. +The first step to offer an intuitive and consistent experience via a single, [unified Camunda 8 REST API](https://camunda.com/blog/2024/03/streamlining-camunda-apis-zeebe-rest-api/) is to provide the Zeebe REST API. With this release, developers can use the Zeebe REST API to manage [Zeebe user tasks](/apis-tools/migration-manuals/migrate-to-zeebe-user-tasks.md), enabling immediate task state changes. The Zeebe REST API includes support for Identity authentication and multi-tenancy, ensuring parity to the Zeebe gRPC API. ### Refactoring suggestions Modeler diff --git a/optimize_sidebars.js b/optimize_sidebars.js index 19965a7faab..7a7b5a97f81 100644 --- a/optimize_sidebars.js +++ b/optimize_sidebars.js @@ -2043,11 +2043,6 @@ module.exports = { }, ], }, - - docsLink( - "Migrate to Zeebe user tasks", - "apis-tools/tasklist-api-rest/migrate-to-zeebe-user-tasks/" - ), ], }, diff --git a/optimize_versioned_sidebars/version-3.14.0-sidebars.json b/optimize_versioned_sidebars/version-3.14.0-sidebars.json index 8524cee6783..638ba5e0288 100644 --- a/optimize_versioned_sidebars/version-3.14.0-sidebars.json +++ b/optimize_versioned_sidebars/version-3.14.0-sidebars.json @@ -2426,11 +2426,6 @@ ] } ] - }, - { - "type": "link", - "label": "Migrate to Zeebe user tasks", - "href": "/docs/apis-tools/tasklist-api-rest/migrate-to-zeebe-user-tasks/" } ] }, diff --git a/sidebars.js b/sidebars.js index 486e440a9d9..c49653ca7d8 100644 --- a/sidebars.js +++ b/sidebars.js @@ -887,6 +887,7 @@ module.exports = { }, { "Migration manuals": [ + "apis-tools/migration-manuals/migrate-to-zeebe-user-tasks", "apis-tools/migration-manuals/migrate-to-camunda-api", ], }, diff --git a/static/.htaccess b/static/.htaccess index ac7a2e8363f..5455aece446 100644 --- a/static/.htaccess +++ b/static/.htaccess @@ -95,6 +95,11 @@ RewriteRule ^docs/reference/bpmn-processes/?(.*)$ /docs/components/modeler/bpmn/ # 8.7: content moves introduced prior to the release of version 8.7. #--------------------------------------------------------------------------------- +# Move migrating to Zeebe user tasks +RewriteRule ^docs/next/apis-tools/tasklist-api-rest/migrate-to-zeebe-user-tasks/?$ /docs/next/apis-tools/migration-manuals/migrate-to-zeebe-user-tasks/$1 [R=301,L] +RewriteRule ^docs/apis-tools/tasklist-api-rest/migrate-to-zeebe-user-tasks/?$ /docs/apis-tools/migration-manuals/migrate-to-zeebe-user-tasks/$1 [R=301,L] +RewriteRule ^docs/8.6/apis-tools/tasklist-api-rest/migrate-to-zeebe-user-tasks/?$ /docs/8.6/apis-tools/migration-manuals/migrate-to-zeebe-user-tasks/$1 [R=301,L] + # Remove community clients RewriteRule ^docs/apis-tools/community-clients/c-sharp/?$ /docs/apis-tools/community-clients/$1 [R=301,L] RewriteRule ^docs/apis-tools/community-clients/micronaut/?$ /docs/apis-tools/community-clients/$1 [R=301,L] diff --git a/versioned_docs/version-8.5/apis-tools/tasklist-api-rest/migrate-to-zeebe-user-tasks.md b/versioned_docs/version-8.5/apis-tools/tasklist-api-rest/migrate-to-zeebe-user-tasks.md index b4f17bacb49..548529ec364 100644 --- a/versioned_docs/version-8.5/apis-tools/tasklist-api-rest/migrate-to-zeebe-user-tasks.md +++ b/versioned_docs/version-8.5/apis-tools/tasklist-api-rest/migrate-to-zeebe-user-tasks.md @@ -12,8 +12,8 @@ import TableTextSmall from "./assets/react-components/TableTextSmall"; import userTaskMigrationDecisionHelperForm from "./assets/forms/userTaskMigrationDecisionHelperForm.js"; import "./assets/css/condensedTable.module.css"; import styles from "./assets/css/cleanImages.module.css"; -import APIArchitectureImg from './assets/img/api-architecture.png'; import ZeebeTaskSelectionImg from './assets/img/zeebe-user-task-selection.png'; +import APIArchitectureImg from './assets/img/api-architecture.png'; Camunda 8.5 introduces a new [user task](/components/modeler/bpmn/user-tasks/user-tasks.md) implementation type: Zeebe user tasks. Zeebe user tasks have several benefits, including: diff --git a/versioned_docs/version-8.5/apis-tools/tasklist-api-rest/tasklist-api-rest-overview.md b/versioned_docs/version-8.5/apis-tools/tasklist-api-rest/tasklist-api-rest-overview.md index 51b479a2a4a..e0203e390e3 100644 --- a/versioned_docs/version-8.5/apis-tools/tasklist-api-rest/tasklist-api-rest-overview.md +++ b/versioned_docs/version-8.5/apis-tools/tasklist-api-rest/tasklist-api-rest-overview.md @@ -5,6 +5,12 @@ sidebar_position: 1 description: "Build applications for human-centered processes by querying human tasks, assigning users, and completing tasks with the Tasklist API." --- +:::note +Camunda introduced [Zeebe user tasks](/apis-tools/tasklist-api-rest/migrate-to-zeebe-user-tasks.md) with `8.5` to build more advanced functionalities. If you use Zeebe user tasks with `8.5`, task management endpoints in the Tasklist API will not work. + +To manage Zeebe user tasks Camunda has introduced the [Zeebe REST API](/apis-tools/zeebe-api-rest/zeebe-api-rest-overview.md), though you can still query Zeebe user tasks with the Tasklist API. +::: + ## Introduction The Tasklist API is a REST API designed to build task applications for human-centered processes. The API allows you to query user tasks, assign users to these tasks, and complete these tasks. diff --git a/versioned_docs/version-8.6/apis-tools/frontend-development/01-task-applications/03-task-application-architecture.md b/versioned_docs/version-8.6/apis-tools/frontend-development/01-task-applications/03-task-application-architecture.md index 50dfb21ef17..b0027b95827 100644 --- a/versioned_docs/version-8.6/apis-tools/frontend-development/01-task-applications/03-task-application-architecture.md +++ b/versioned_docs/version-8.6/apis-tools/frontend-development/01-task-applications/03-task-application-architecture.md @@ -6,10 +6,10 @@ description: "Understand and decide on the architecture of your task application A typical task application architecture consists of a task application frontend, a backend-for-frontend, and one or more data sources or services that contain business data relevant for the application users to perform their work. The backend implements Camunda Zeebe and Tasklist clients to retrieve and interact with tasks via Camunda APIs. For historical process instance data, Operate is also required. -Depending on the user task implementation type (job-based vs Zeebe user task) you use in your processes, you need to run either the Tasklist or Zeebe client to run operations on task. Task, form, and variable retrieval happens via the Tasklist API. Learn more about the differences of the task implementation types in the [migration guide for Zeebe user tasks](/apis-tools/tasklist-api-rest/migrate-to-zeebe-user-tasks.md). +Depending on the user task implementation type (job worker-based vs Zeebe user task) you use in your processes, you need to run either the Tasklist or Zeebe client to run operations on task. Task, form, and variable retrieval happens via the API. Learn more about the differences of the task implementation types in the [migration guide for Zeebe user tasks](/apis-tools/migration-manuals/migrate-to-zeebe-user-tasks.md). :::tip -Starting a completely new project? Use only Zeebe user tasks to simplify your implementation. +Starting a new project? Use Zeebe user tasks to simplify your implementation. ::: Click on any element of this diagram to jump to the documentation page for the respective component: @@ -72,14 +72,14 @@ style Tasklist stroke:#10c95d,color:#000 click Forms "../../forms/introduction-to-forms" click Rest "../../../tasklist-api-rest/tasklist-api-rest-overview" -click Job "../../../tasklist-api-rest/migrate-to-zeebe-user-tasks" -click ZeebeTasks "../../../tasklist-api-rest/migrate-to-zeebe-user-tasks" +click Job "../../../migration-manuals/migrate-to-zeebe-user-tasks" +click ZeebeTasks "../../../migration-manuals/migrate-to-zeebe-user-tasks" click ZeebeRest "../../../zeebe-api-rest/zeebe-api-rest-overview" ``` Follow these resources to learn more about the individual components: -- Familiarize yourself with the [Tasklist API](/apis-tools/tasklist-api-rest/tasklist-api-rest-overview.md) for task, variable, and form retrieval, and to run operations on job-based user tasks. -- Learn how to use the [Zeebe API](/apis-tools/zeebe-api-rest/zeebe-api-rest-overview.md) to run operations on Zeebe-based user tasks. +- Learn how to use the [Camunda 8 API](/apis-tools/camunda-api-rest/specifications/assign-user-task.api.mdx) for task, variable, and form retrieval, and to run operations on Zeebe user tasks. +- Familiarize yourself with the [Tasklist API](/apis-tools/tasklist-api-rest/tasklist-api-rest-overview.md) to run operations on job worker-based user tasks. - Understand how to design, embed, and customize [forms](/apis-tools/frontend-development/03-forms/01-introduction-to-forms.md). - Understand how this architecture fits into the overall Camunda architecture with the [Java greenfield stack](/components/best-practices/architecture/deciding-about-your-stack.md). diff --git a/versioned_docs/version-8.6/apis-tools/tasklist-api-rest/migrate-to-zeebe-user-tasks.md b/versioned_docs/version-8.6/apis-tools/migration-manuals/migrate-to-zeebe-user-tasks.md similarity index 57% rename from versioned_docs/version-8.6/apis-tools/tasklist-api-rest/migrate-to-zeebe-user-tasks.md rename to versioned_docs/version-8.6/apis-tools/migration-manuals/migrate-to-zeebe-user-tasks.md index b4f17bacb49..d1f19118f98 100644 --- a/versioned_docs/version-8.6/apis-tools/tasklist-api-rest/migrate-to-zeebe-user-tasks.md +++ b/versioned_docs/version-8.6/apis-tools/migration-manuals/migrate-to-zeebe-user-tasks.md @@ -1,32 +1,32 @@ --- id: migrate-to-zeebe-user-tasks title: Migrate to Zeebe user tasks -description: "Learn how to migrate job worker-based user tasks to Zeebe-based tasks." +description: "Learn how to migrate job worker-based user tasks to Zeebe user tasks." --- import DocCardList from '@theme/DocCardList'; import FormViewer from "@site/src/mdx/FormViewer"; -import YesItem from "./assets/react-components/YesItem"; -import NoItem from "./assets/react-components/NoItem"; -import TableTextSmall from "./assets/react-components/TableTextSmall"; -import userTaskMigrationDecisionHelperForm from "./assets/forms/userTaskMigrationDecisionHelperForm.js"; -import "./assets/css/condensedTable.module.css"; -import styles from "./assets/css/cleanImages.module.css"; -import APIArchitectureImg from './assets/img/api-architecture.png'; -import ZeebeTaskSelectionImg from './assets/img/zeebe-user-task-selection.png'; - -Camunda 8.5 introduces a new [user task](/components/modeler/bpmn/user-tasks/user-tasks.md) implementation type: Zeebe user tasks. -Zeebe user tasks have several benefits, including: +import YesItem from "../tasklist-api-rest/assets/react-components/YesItem"; +import NoItem from "../tasklist-api-rest/assets/react-components/NoItem"; +import TableTextSmall from "../tasklist-api-rest/assets/react-components/TableTextSmall"; +import userTaskMigrationDecisionHelperForm from "../tasklist-api-rest/assets/forms/userTaskMigrationDecisionHelperForm.js"; +import "../tasklist-api-rest/assets/css/condensedTable.module.css"; +import styles from "../tasklist-api-rest/assets/css/cleanImages.module.css"; +import ZeebeTaskSelectionImg from '../tasklist-api-rest/assets/img/zeebe-user-task-selection.png'; + +Camunda 8.5 introduced a new [user task](/components/modeler/bpmn/user-tasks/user-tasks.md) implementation type: Zeebe user tasks. + +Zeebe user tasks have several benefits compared to job worked-based user tasks. It includes: - Running directly on the automation engine for high performance. - Removing dependencies and round trips to Tasklist. -- A more powerful API that supports the full task lifecycle. +- A powerful API that supports the full task lifecycle. In this guide, you will learn: - Under which circumstances and when you should migrate. - How to estimate the impact on a project. -- The steps you need to take for a successful migration without interrupting your operations. +- Steps you need to take for a successful migration without interrupting your operations. ## Decide on your migration path @@ -34,17 +34,6 @@ Zeebe user tasks require migration of the user tasks in both your diagrams and t With this in mind, you can migrate at your own pace. If you should migrate now or later, and what is required to migrate depends on your current setup and future plans. -Use the following decision helper questionnaire to figure out what's right for you: - - - ### Task type differences Learn the differences between both task types and make an informed decision, and understand the new capabilities of Zeebe user tasks. Refer to this table for important high-level differences of the two task types: @@ -58,7 +47,7 @@ Learn the differences between both task types and make an informed decision, and
    Zeebe user tasks
    - Recommended for new projects + Recommended for existing and new projects @@ -91,11 +80,11 @@ Learn the differences between both task types and make an informed decision, and
    Partially
    Queries, GET tasks, forms, variables - ℹ Currently, you must use Zeebe and Tasklist APIs to use Zeebe user tasks + ℹ Currently, you must use the Camunda 8 and Tasklist APIs to use Zeebe user tasks - Supports Zeebe API + Supports Camunda 8 API @@ -123,7 +112,6 @@ Learn the differences between both task types and make an informed decision, and - Task listeners will be introduced in a future release @@ -146,10 +134,9 @@ Learn the differences between both task types and make an informed decision, and Recommendations You can continue to use this task type on existing projects when you have a custom task application running on it and do not require any of the above features. - Refer to the decision helper above for a tailored recommendation. - Use this task type on any new projects when you run Tasklist. + Recommended for existing and new projects when you run Tasklist. Migrate existing projects and task applications/clients to this task type when you require one of the features above, or the following use cases:
      @@ -161,12 +148,11 @@ Learn the differences between both task types and make an informed decision, and
    • Enrich tasks with business data
    - Refer to the decision helper above for a tailored recommendation. -## Switch the implementation type of your user tasks +## Switch the implementation type of user tasks We recommend you migrate process-by-process, allowing you to thoroughly test the processes in your test environments or via your [CI/CD](/guides/devops-lifecycle/integrate-web-modeler-in-ci-cd.md). To do this, take the following steps: @@ -181,176 +167,130 @@ We recommend you migrate process-by-process, allowing you to thoroughly test the Repeat these steps for all user tasks in the process. Then, deploy the process to your development cluster and test it by running the process and ensuring your custom task applications work. -## Use the new Zeebe Task API +## Use the Camunda 8 API :::note The Tasklist REST API is not deprecated, and you still need it for queries on both task types. ::: -Operations on Zeebe user tasks which modify the task state have to be performed using the new Zeebe REST API. However, queries and adjacent operations still require the Tasklist REST API. The following table provides a breakdown of which operations are supported in which API, and for which user tasks. +The following table provides a breakdown of which operations are supported in which API, and for which user tasks. - + - - - + + - - - + + + + + + + + - - + + - - - + + + - - + + - - + + - + - - - + + +
    Operation Tasklist APIZeebe Task API (8.5)Camunda 8 API
    Query tasks All types← Use Tasklist APISupported from 8.6+
    Get task All types← Use Tasklist APIQuery user task Job worker-based user tasks Zeebe user tasks
    Get user task Job worker-based user tasks Zeebe user tasks
    Retrieve task variables All types← Use Tasklist API Job worker-based user tasks Zeebe user tasks
    Get task form All types← Use Tasklist APIGet user task form Job worker-based user tasks Zeebe user tasks
    Change task assignment Job worker-based tasks Zeebe tasks Job worker-based user tasks Zeebe user tasks
    Complete task Job worker-based tasks Zeebe tasks Job worker-based user tasks Zeebe user tasks
    Update task - Zeebe tasks Zeebe user tasks
    Safe and retrieve draft variables All types← Use Tasklist APISave and retrieve draft variables Job worker-based user tasks -
    -You can also operate both task types at the same time in the same application utilizing both APIs. We recommend this for a smooth migration, but you should eventually update all processes to use the new task type to use all benefits. The following image illustrates how to route API calls to the respective APIs: - -Task API Architecture - -The major changes are: - -- Create and maintain new, additional secrets for the Zeebe REST API. -- Call dedicated endpoints on separate components (Zeebe vs. Tasklist) for all state modifications on tasks for the respective task types. -- Manage new request/response objects. - The following table outlines the respective endpoints. Click the endpoints to follow to the API documentation and inspect the differences in the request and response objects. - - - - - - - - - - - - - - - - - - - - - + - + - + - +
    Operation Tasklist APIZeebe Task API (8.5)
    Query tasks - - POST /tasks/search - - ← Use Tasklist API
    Get task - - GET /tasks/:taskId - - ← Use Tasklist API
    Retrieve task variables - - GET /variables/:variableId - -
    - - POST /tasks/:taskId/variables/search - -
    ← Use Tasklist API
    Get task form - - GET /forms/:formId - - ← Use Tasklist APICamunda 8 API
    Assign a task - + PATCH /tasks/:taskId/assign - - POST /user-tasks/:taskKey/assignment + + POST /user-tasks/:userTaskKey/assignment
    Unassign a task - + PATCH /tasks/:taskId/unassign - - DELETE /user-tasks/:taskKey/assignee + + DELETE /user-tasks/:userTaskKey/assignee
    Complete task - + PATCH /tasks/:taskId/complete - - POST /user-tasks/:taskKey/completion + + POST /user-tasks/:userTaskKey/completion
    Update task-- - - PATCH /user-tasks/:taskKey + + PATCH /user-tasks/:userTaskKey
    Safe and retrieve draft variablesSave and retrieve draft variables - + POST /tasks/:taskId/variables ← Use Tasklist API-
    @@ -373,9 +313,9 @@ docId:"apis-tools/tasklist-api-rest/tasklist-api-rest-overview" }, { type:"link", -href:"/docs/next/apis-tools/zeebe-api-rest/zeebe-api-rest-overview/", -label: "Zeebe API (REST)", -docId:"apis-tools/zeebe-api-rest/zeebe-api-rest-overview" +href:"/docs/next/apis-tools/camunda-api-rest/camunda-api-rest-overview/", +label: "Camunda 8 API (REST)", +docId:"apis-tools/camunda-api-rest/camunda-api-rest-overview" } ]}/> @@ -383,6 +323,6 @@ docId:"apis-tools/zeebe-api-rest/zeebe-api-rest-overview" If your task application does not work properly after migration, check the following: -- **The endpoints return specific error messages when you run them on the wrong task type**: Ensure to call the right endpoint for the right task type, c.f. above [table](#use-the-new-zeebe-task-api). +- **The endpoints return specific error messages when you run them on the wrong task type**: Ensure to call the right endpoint for the right task type, c.f. above [table](#use-the-new-camunda-8-api). - **Forms do not appear**: Ensure you have extracted embedded forms, if any, and [transformed them into linked forms](/components/modeler/bpmn/user-tasks/user-tasks.md#camunda-form-linked), before you change the task type implementation. - **Task update operation does not work**: The update operation is only available to Zeebe user tasks. diff --git a/versioned_docs/version-8.6/apis-tools/tasklist-api-rest/sidebar-schema.js b/versioned_docs/version-8.6/apis-tools/tasklist-api-rest/sidebar-schema.js index 517c97c4df8..ebb41a15e74 100644 --- a/versioned_docs/version-8.6/apis-tools/tasklist-api-rest/sidebar-schema.js +++ b/versioned_docs/version-8.6/apis-tools/tasklist-api-rest/sidebar-schema.js @@ -7,6 +7,5 @@ module.exports = { { Specifications: require("./specifications/sidebar.js"), }, - "apis-tools/tasklist-api-rest/migrate-to-zeebe-user-tasks", ], }; diff --git a/versioned_docs/version-8.6/apis-tools/tasklist-api-rest/tasklist-api-rest-overview.md b/versioned_docs/version-8.6/apis-tools/tasklist-api-rest/tasklist-api-rest-overview.md index 94cf88764af..31bedd5f7cd 100644 --- a/versioned_docs/version-8.6/apis-tools/tasklist-api-rest/tasklist-api-rest-overview.md +++ b/versioned_docs/version-8.6/apis-tools/tasklist-api-rest/tasklist-api-rest-overview.md @@ -5,6 +5,12 @@ sidebar_position: 1 description: "Build applications for human-centered processes by querying user tasks, assigning users, and completing tasks with the Tasklist API." --- +:::note +Camunda introduced the [Camunda 8 REST API](/apis-tools/camunda-api-rest/camunda-api-rest-overview.md) with `8.6` to manage and query process entities such as processes, decisions, forms, and user tasks. + +Camunda has also introduced [Zeebe user tasks](/apis-tools/migration-manuals/migrate-to-zeebe-user-tasks.md) to build more advanced functionalities. If you use Zeebe user tasks with `8.6`, task management endpoints in the Tasklist API will not work. +::: + ## Introduction The Tasklist API is a REST API designed to build task applications for human-centered processes. The API allows you to query user tasks, assign users to these tasks, and complete these tasks. diff --git a/versioned_docs/version-8.6/apis-tools/zeebe-api-rest/tutorial.md b/versioned_docs/version-8.6/apis-tools/zeebe-api-rest/tutorial.md index ec299cbe3a6..2bb1795037a 100644 --- a/versioned_docs/version-8.6/apis-tools/zeebe-api-rest/tutorial.md +++ b/versioned_docs/version-8.6/apis-tools/zeebe-api-rest/tutorial.md @@ -41,7 +41,7 @@ In this tutorial, we will execute arguments to assign and unassign a user to and ## Assign a Zeebe user task (POST) :::note -In this tutorial, you will capture a **Zeebe user task** ID to assign and unassign users in this API. Camunda 8.5 introduced this new [user task](/components/modeler/bpmn/user-tasks/user-tasks.md) implementation type, and these Zeebe user tasks are different from job worker-based user tasks. See more details on task type differences in the [migrating to Zeebe user tasks documentation](/apis-tools/tasklist-api-rest/migrate-to-zeebe-user-tasks.md#task-type-differences). +In this tutorial, you will capture a **Zeebe user task** ID to assign and unassign users in this API. Camunda 8.5 introduced this new [user task](/components/modeler/bpmn/user-tasks/user-tasks.md) implementation type, and these Zeebe user tasks are different from job worker-based user tasks. See more details on task type differences in the [migrating to Zeebe user tasks documentation](/apis-tools/migration-manuals/migrate-to-zeebe-user-tasks.md#task-type-differences). ::: First, let's script an API call to assign a Zeebe user task. diff --git a/versioned_docs/version-8.6/components/modeler/bpmn/user-tasks/user-tasks.md b/versioned_docs/version-8.6/components/modeler/bpmn/user-tasks/user-tasks.md index 5212b2a3b2c..90a64a6191c 100644 --- a/versioned_docs/version-8.6/components/modeler/bpmn/user-tasks/user-tasks.md +++ b/versioned_docs/version-8.6/components/modeler/bpmn/user-tasks/user-tasks.md @@ -162,7 +162,7 @@ A user task does not have to be managed by Zeebe. Instead, you can also use job workers to implement a custom user task logic. Note that you will lose all the task lifecycle and state management features that Zeebe provides and will have to implement them yourself. Use job workers only in case you require a very specific implementation of user tasks that can't be implemented on top of Zeebe user tasks. :::info -If you started using Camunda 8 with version 8.4 or a lower version and upgraded to 8.5 or newer, your user tasks are probably implemented as job workers. Refer to the [migration guide](/apis-tools/tasklist-api-rest/migrate-to-zeebe-user-tasks.md) to find a detailed list of the differences between the task implementation types and learn how to migrate to Zeebe user tasks. +If you started using Camunda 8 with version 8.4 or a lower version and upgraded to 8.5 or newer, your user tasks are probably implemented as job workers. Refer to the [migration guide](/apis-tools/migration-manuals/migrate-to-zeebe-user-tasks.md) to find a detailed list of the differences between the task implementation types and learn how to migrate to Zeebe user tasks. ::: You can define a job worker implementation for a user task by removing its `zeebe:userTask` extension element. diff --git a/versioned_docs/version-8.6/components/modeler/web-modeler/advanced-modeling/form-linking.md b/versioned_docs/version-8.6/components/modeler/web-modeler/advanced-modeling/form-linking.md index c7cf43464fe..cf43c6b50c5 100644 --- a/versioned_docs/version-8.6/components/modeler/web-modeler/advanced-modeling/form-linking.md +++ b/versioned_docs/version-8.6/components/modeler/web-modeler/advanced-modeling/form-linking.md @@ -89,6 +89,10 @@ To correct any instances affected by this issue, we recommend the following step ### Camunda Form (embedded) +:::info +Embedded forms are supported only by job worker-based user tasks and are not available for the [Zeebe user task implementation type](/components/modeler/bpmn/user-tasks/user-tasks.md#user-task-implementation-types). +::: + When choosing **Camunda Form (embedded)** as type you have the option to directly paste the form's JSON schema into the **Form JSON configuration** field of the properties panel. The form will be embedded directly into the BPMN diagram's XML representation. diff --git a/versioned_docs/version-8.6/reference/release-notes/850.md b/versioned_docs/version-8.6/reference/release-notes/850.md index 43f3806758c..d514f55adca 100644 --- a/versioned_docs/version-8.6/reference/release-notes/850.md +++ b/versioned_docs/version-8.6/reference/release-notes/850.md @@ -108,7 +108,7 @@ The first iteration of this feature brings back existing features from Camunda 7 -The first step to offer an intuitive and consistent experience via a single, [unified Camunda 8 REST API](https://camunda.com/blog/2024/03/streamlining-camunda-apis-zeebe-rest-api/) is to provide the Zeebe REST API. With this release, developers can use the Zeebe REST API to manage [Zeebe user tasks](/apis-tools/tasklist-api-rest/migrate-to-zeebe-user-tasks.md), enabling immediate task state changes. The Zeebe REST API includes support for Identity authentication and multi-tenancy, ensuring parity to the Zeebe gRPC API. +The first step to offer an intuitive and consistent experience via a single, [unified Camunda 8 REST API](https://camunda.com/blog/2024/03/streamlining-camunda-apis-zeebe-rest-api/) is to provide the Zeebe REST API. With this release, developers can use the Zeebe REST API to manage [Zeebe user tasks](/apis-tools/migration-manuals/migrate-to-zeebe-user-tasks.md), enabling immediate task state changes. The Zeebe REST API includes support for Identity authentication and multi-tenancy, ensuring parity to the Zeebe gRPC API. ### Refactoring suggestions Modeler diff --git a/versioned_sidebars/version-8.6-sidebars.json b/versioned_sidebars/version-8.6-sidebars.json index b78cbba1c69..66f10535b88 100644 --- a/versioned_sidebars/version-8.6-sidebars.json +++ b/versioned_sidebars/version-8.6-sidebars.json @@ -1592,8 +1592,7 @@ ] } ] - }, - "apis-tools/tasklist-api-rest/migrate-to-zeebe-user-tasks" + } ] }, { @@ -1765,8 +1764,14 @@ ] } ] + }, + { + "Migration manuals": [ + "apis-tools/migration-manuals/migrate-to-zeebe-user-tasks" + ] } ], + "Reference": [ "reference/overview", "reference/announcements", From dbb5f6c6ccf6ef39aeb60181a4bbaed5a3d37dff Mon Sep 17 00:00:00 2001 From: Jeremy Jacobi <108456325+JacobiCamunda@users.noreply.github.com> Date: Mon, 9 Dec 2024 10:11:33 +0100 Subject: [PATCH 2/9] feat(web-modeler): add git-sync self-hosted part (#4630) * feat(web-modeler): add git-sync self-hosted part * incorporate review feedback * feat(web-modeler): add part about using application id as alternative in git-sync * Update docs/components/modeler/web-modeler/git-sync.md Co-authored-by: Cole Isaac <82131455+conceptualshark@users.noreply.github.com> --------- Co-authored-by: Cole Isaac <82131455+conceptualshark@users.noreply.github.com> --- docs/components/modeler/web-modeler/git-sync.md | 9 +++++++-- .../components/modeler/web-modeler/git-sync.md | 9 +++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/docs/components/modeler/web-modeler/git-sync.md b/docs/components/modeler/web-modeler/git-sync.md index 2f6668310d9..a8ebc77bf36 100644 --- a/docs/components/modeler/web-modeler/git-sync.md +++ b/docs/components/modeler/web-modeler/git-sync.md @@ -36,18 +36,22 @@ Click **Create GitHub App** to finish. 3. Select **Only select repositories**, and choose the repository to sync with Web Modeler. 4. Once redirected to your application's installation page, copy the **Installation ID** located at the end of the page's URL: `https://github.com/settings/installations/{installation_id}`. -### Configure GitHub in Web Modeler +### [Configure GitHub in Web Modeler](#configure-github-in-web-modeler) :::note An organization administration account (or project administrator in Camunda Self-Managed) is required for the initial GitHub configuration. ::: +:::note +When using a self-hosted GitHub instance, ensure the environment variable `CAMUNDA_MODELER_GITSYNC_GITHUB_BASEURL` is set to the API URL of your self-hosted GitHub instance. It usually looks like `http(s)://HOSTNAME/api/v3`. Refer to [GitHub documentation](https://docs.github.com/en/enterprise-server@3.15/rest/enterprise-admin?apiVersion=2022-11-28#endpoint-urls) and choose the correct enterprise server version. +::: + 1. Within Web Modeler, navigate to the process application you would like to connect to GitHub, and click **Connect GitHub**. 2. Provide the following information in the GitHub Configuration modal: - **Installation ID:** Found in the URL of your GitHub App's installation page. - - **Client ID:** Found in your GitHub App's settings page. + - **Client ID:** Found in your GitHub App's settings page. You can also use Application ID as an alternative. (If you are using GitHub Enterprise Server 3.13 or prior, Application ID is required.) - **Private Key:** The contents of the .pem file downloaded from your GitHub App's settings page. - **GitHub repository URL:** The base URL of the repository you want to sync with, for example `https://github.com/camunda/example-repo`. The URL cannot contain the `.git` extension or a folder path. - **Branch name:** The branch name to use for merging and managing changes. @@ -130,3 +134,4 @@ Creating multiple copies of a process application can complicate navigation and - Actions which alter the SHA of the commit to which Web Modeler is synced (for example, squash) may cause synchronization errors. - Timeouts may occur during a sync. In the event of a timeout, close the modal and retry the synchronization. - A single synchronization action is limited to incorporating a maximum of 250 commits or making changes to up to 300 files, regardless of whether these changes affect the Web Modeler files directly. Be aware that Web Modeler does not provide a notification when these thresholds are exceeded. Should you encounter this limitation, it may be necessary to initiate a fresh synchronization. A fresh synchronization fetches all the files in the repository without relying on the incremental changes, thus bypassing the limitations. This can be achieved by either changing the branch or modifying the GitHub repository URL. +- Using self-hosted instances of Git providers may require additional configuration. Refer to the Web Modeler [configuration](#configure-github-in-web-modeler) for more details. diff --git a/versioned_docs/version-8.6/components/modeler/web-modeler/git-sync.md b/versioned_docs/version-8.6/components/modeler/web-modeler/git-sync.md index 8d0ed17309d..bc40d5ede1f 100644 --- a/versioned_docs/version-8.6/components/modeler/web-modeler/git-sync.md +++ b/versioned_docs/version-8.6/components/modeler/web-modeler/git-sync.md @@ -36,18 +36,22 @@ Click **Create GitHub App** to finish. 3. Select **Only select repositories**, and choose the repository to sync with Web Modeler. 4. Once redirected to your application's installation page, copy the **Installation ID** located at the end of the page's URL: `https://github.com/settings/installations/{installation_id}`. -### Configure GitHub in Web Modeler +### [Configure GitHub in Web Modeler](#configure-github-in-web-modeler) :::note An organization administration account (or project administrator in Camunda Self-Managed) is required for the initial GitHub configuration. ::: +:::note +When using a self-hosted GitHub instance, ensure the environment variable `CAMUNDA_MODELER_GITSYNC_GITHUB_BASEURL` is set to the API URL of your self-hosted GitHub instance. It usually looks like `http(s)://HOSTNAME/api/v3`. Refer to [GitHub documentation](https://docs.github.com/en/enterprise-server@3.15/rest/enterprise-admin?apiVersion=2022-11-28#endpoint-urls) and choose the correct enterprise server version. +::: + 1. Within Web Modeler, navigate to the process application you would like to connect to GitHub, and click **Connect GitHub**. 2. Provide the following information in the GitHub Configuration modal: - **Installation ID:** Found in the URL of your GitHub App's installation page. - - **Client ID:** Found in your GitHub App's settings page. + - **Client ID:** Found in your GitHub App's settings page. You can also use Application ID as an alternative. (If you are using GitHub Enterprise Server 3.13 or prior, you **have** to use Application ID) - **Private Key:** The contents of the .pem file downloaded from your GitHub App's settings page. - **GitHub repository URL:** The base URL of the repository you want to sync with, for example `https://github.com/camunda/example-repo`. The URL cannot contain the `.git` extension or a folder path. - **Branch name:** The branch name to use for merging and managing changes. @@ -96,3 +100,4 @@ Existing GitHub configurations can be edited from the gear icon beside the **Syn - Actions which alter the SHA of the commit to which Web Modeler is synced (for example, squash) may cause synchronization errors. - Timeouts may occur during a sync. In the event of a timeout, close the modal and retry the synchronization. - A single synchronization action is limited to incorporating a maximum of 250 commits or making changes to up to 300 files, regardless of whether these changes affect the Web Modeler files directly. Be aware that Web Modeler does not provide a notification when these thresholds are exceeded. Should you encounter this limitation, it may be necessary to initiate a fresh synchronization. A fresh synchronization fetches all the files in the repository without relying on the incremental changes, thus bypassing the limitations. This can be achieved by either changing the branch or modifying the GitHub repository URL. +- Using self-hosted instances of Git providers may require additional configuration. Refer to the Web Modeler [configuration](#configure-github-in-web-modeler) for more details. From 7eb91188bb0c9975c101c67cda886b469a124538 Mon Sep 17 00:00:00 2001 From: Mark Farkas <119574841+markfarkas-camunda@users.noreply.github.com> Date: Mon, 9 Dec 2024 12:26:11 +0100 Subject: [PATCH 3/9] fix(template-generator): remove saas only badge (#4725) --- .../custom-built-connectors/connector-template-generator.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/components/connectors/custom-built-connectors/connector-template-generator.md b/docs/components/connectors/custom-built-connectors/connector-template-generator.md index d0d919499ea..09eeaf978fe 100644 --- a/docs/components/connectors/custom-built-connectors/connector-template-generator.md +++ b/docs/components/connectors/custom-built-connectors/connector-template-generator.md @@ -4,8 +4,6 @@ title: Generate a Connector template description: Learn how to generate Connector templates for easier custom Connector creation. --- -Camunda 8 SaaS only - You can configure and automatically generate a custom [Connector template](/components/connectors/custom-built-connectors/connector-templates.md) in Web Modeler. You can start from a blank template or import an existing API definition such as an [OpenAPI specification](https://swagger.io/resources/open-api/), [Swagger specification](https://swagger.io/resources/open-api/), or a [Postman collection](https://www.postman.com/collection/). For example, download a Postman collection as a YAML file, import this into the generator, and choose which methods to include in the generated template. From 0691fddb3fdb08ec2397432653278ac720daf516 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=20=E9=8A=8D?= Date: Mon, 9 Dec 2024 21:47:39 +0800 Subject: [PATCH 4/9] feat(feel): Add new built-in function (#4713) Add new built-in function of the FEEL engine to the FEEL documentation. --- .../feel-built-in-functions-list.md | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/docs/components/modeler/feel/builtin-functions/feel-built-in-functions-list.md b/docs/components/modeler/feel/builtin-functions/feel-built-in-functions-list.md index 9f6b2358e5a..63e8c984897 100644 --- a/docs/components/modeler/feel/builtin-functions/feel-built-in-functions-list.md +++ b/docs/components/modeler/feel/builtin-functions/feel-built-in-functions-list.md @@ -621,3 +621,30 @@ is empty([]) is empty([1,2,3]) // false ``` + +## partition(list, size) + + + +Returns consecutive sublists of a list, each of the same size (the final list may be smaller). + +If `size` is less than `0`, it returns `null`. + +**Function signature** + +```feel +partition(list: list, size: number): list +``` + +**Examples** + +```feel +partition([1,2,3,4,5], 2) +// [[1,2], [3,4], [5]] + +partition([], 2) +// [] + +partition([1,2], 0) +// null +``` From d1b1dc0148558eb159b89b95c1a455aa5d0350fe Mon Sep 17 00:00:00 2001 From: Mark Sellings Date: Mon, 9 Dec 2024 14:20:11 +0000 Subject: [PATCH 5/9] Remove compensation event note (#4728) --- docs/components/concepts/workflow-patterns.md | 4 ---- .../version-8.5/components/concepts/workflow-patterns.md | 4 ---- .../version-8.6/components/concepts/workflow-patterns.md | 4 ---- 3 files changed, 12 deletions(-) diff --git a/docs/components/concepts/workflow-patterns.md b/docs/components/concepts/workflow-patterns.md index ace1b2cbd69..8d148ee15e5 100644 --- a/docs/components/concepts/workflow-patterns.md +++ b/docs/components/concepts/workflow-patterns.md @@ -276,10 +276,6 @@ An important problem to solve is how to roll back a business transaction in case In BPMN, you can use [compensation events](/components/modeler/bpmn/bpmn-coverage.md) to easily implement compensations in your processes. -:::note -The compensation event is supported in Camunda 7, but not yet in Camunda 8. It is on the roadmap and will eventually be available in Camunda 8. -::: -
    1 diff --git a/versioned_docs/version-8.5/components/concepts/workflow-patterns.md b/versioned_docs/version-8.5/components/concepts/workflow-patterns.md index ace1b2cbd69..8d148ee15e5 100644 --- a/versioned_docs/version-8.5/components/concepts/workflow-patterns.md +++ b/versioned_docs/version-8.5/components/concepts/workflow-patterns.md @@ -276,10 +276,6 @@ An important problem to solve is how to roll back a business transaction in case In BPMN, you can use [compensation events](/components/modeler/bpmn/bpmn-coverage.md) to easily implement compensations in your processes. -:::note -The compensation event is supported in Camunda 7, but not yet in Camunda 8. It is on the roadmap and will eventually be available in Camunda 8. -::: -
    1 diff --git a/versioned_docs/version-8.6/components/concepts/workflow-patterns.md b/versioned_docs/version-8.6/components/concepts/workflow-patterns.md index ace1b2cbd69..8d148ee15e5 100644 --- a/versioned_docs/version-8.6/components/concepts/workflow-patterns.md +++ b/versioned_docs/version-8.6/components/concepts/workflow-patterns.md @@ -276,10 +276,6 @@ An important problem to solve is how to roll back a business transaction in case In BPMN, you can use [compensation events](/components/modeler/bpmn/bpmn-coverage.md) to easily implement compensations in your processes. -:::note -The compensation event is supported in Camunda 7, but not yet in Camunda 8. It is on the roadmap and will eventually be available in Camunda 8. -::: -
    1 From 8bd7afbeaf13065fa2378890444071ab31db9161 Mon Sep 17 00:00:00 2001 From: Amara Graham Date: Mon, 9 Dec 2024 08:24:54 -0600 Subject: [PATCH 6/9] add URI (#4724) --- docs/apis-tools/java-client/index.md | 4 ++-- versioned_docs/version-8.6/apis-tools/java-client/index.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/apis-tools/java-client/index.md b/docs/apis-tools/java-client/index.md index 0768a607df7..30212b1bdc8 100644 --- a/docs/apis-tools/java-client/index.md +++ b/docs/apis-tools/java-client/index.md @@ -52,8 +52,8 @@ In Java code, instantiate the client as follows: .build(); try (ZeebeClient client = ZeebeClient.newClientBuilder() - .grpcAddress(zeebeGrpc) - .restAddress(zeebeRest) + .grpcAddress(URI.create(zeebeGrpc)) + .restAddress(URI.create(zeebeRest)) .credentialsProvider(credentialsProvider) .build()) { client.newTopologyRequest().send().join(); diff --git a/versioned_docs/version-8.6/apis-tools/java-client/index.md b/versioned_docs/version-8.6/apis-tools/java-client/index.md index 0768a607df7..30212b1bdc8 100644 --- a/versioned_docs/version-8.6/apis-tools/java-client/index.md +++ b/versioned_docs/version-8.6/apis-tools/java-client/index.md @@ -52,8 +52,8 @@ In Java code, instantiate the client as follows: .build(); try (ZeebeClient client = ZeebeClient.newClientBuilder() - .grpcAddress(zeebeGrpc) - .restAddress(zeebeRest) + .grpcAddress(URI.create(zeebeGrpc)) + .restAddress(URI.create(zeebeRest)) .credentialsProvider(credentialsProvider) .build()) { client.newTopologyRequest().send().join(); From 256f7bb6809b17d1d3f3fe06fc095b7ad8332371 Mon Sep 17 00:00:00 2001 From: Amara Graham Date: Mon, 9 Dec 2024 09:00:27 -0600 Subject: [PATCH 7/9] add note (#4719) --- docs/components/modeler/web-modeler/camunda-marketplace.md | 4 ++++ .../components/modeler/web-modeler/camunda-marketplace.md | 4 ++++ .../components/modeler/web-modeler/camunda-marketplace.md | 4 ++++ .../components/modeler/web-modeler/camunda-marketplace.md | 4 ++++ .../components/modeler/web-modeler/camunda-marketplace.md | 4 ++++ 5 files changed, 20 insertions(+) diff --git a/docs/components/modeler/web-modeler/camunda-marketplace.md b/docs/components/modeler/web-modeler/camunda-marketplace.md index 1e366d34ebb..0842066baee 100644 --- a/docs/components/modeler/web-modeler/camunda-marketplace.md +++ b/docs/components/modeler/web-modeler/camunda-marketplace.md @@ -12,6 +12,10 @@ If you are a **[Web Modeler Self-Managed](/self-managed/modeler/web-modeler/inst ## Browse Marketplace Connectors +:::note +Connectors created by partners or the community are not part of the commercial Camunda product. Camunda does not support these Connectors as part of its commercial services to enterprise customers. Please evaluate each client to make sure it meets your requirements before using. +::: + To navigate to the Camunda Marketplace, take the following steps: 1. Log in to your Camunda account. diff --git a/versioned_docs/version-8.3/components/modeler/web-modeler/camunda-marketplace.md b/versioned_docs/version-8.3/components/modeler/web-modeler/camunda-marketplace.md index 9b026b9d57a..5fee9c721d8 100644 --- a/versioned_docs/version-8.3/components/modeler/web-modeler/camunda-marketplace.md +++ b/versioned_docs/version-8.3/components/modeler/web-modeler/camunda-marketplace.md @@ -14,6 +14,10 @@ The Camunda Marketplace can be accessed via your [browser](https://marketplace.c ## Visit the Camunda Marketplace +:::note +Connectors created by partners or the community are not part of the commercial Camunda product. Camunda does not support these Connectors as part of its commercial services to enterprise customers. Please evaluate each client to make sure it meets your requirements before using. +::: + To navigate to the Camunda Marketplace, take the following steps: 1. Log in to your Camunda account, and navigate to Web Modeler using the **Camunda components** icon in the top left corner of your console. Click **Modeler**. diff --git a/versioned_docs/version-8.4/components/modeler/web-modeler/camunda-marketplace.md b/versioned_docs/version-8.4/components/modeler/web-modeler/camunda-marketplace.md index 9b026b9d57a..5fee9c721d8 100644 --- a/versioned_docs/version-8.4/components/modeler/web-modeler/camunda-marketplace.md +++ b/versioned_docs/version-8.4/components/modeler/web-modeler/camunda-marketplace.md @@ -14,6 +14,10 @@ The Camunda Marketplace can be accessed via your [browser](https://marketplace.c ## Visit the Camunda Marketplace +:::note +Connectors created by partners or the community are not part of the commercial Camunda product. Camunda does not support these Connectors as part of its commercial services to enterprise customers. Please evaluate each client to make sure it meets your requirements before using. +::: + To navigate to the Camunda Marketplace, take the following steps: 1. Log in to your Camunda account, and navigate to Web Modeler using the **Camunda components** icon in the top left corner of your console. Click **Modeler**. diff --git a/versioned_docs/version-8.5/components/modeler/web-modeler/camunda-marketplace.md b/versioned_docs/version-8.5/components/modeler/web-modeler/camunda-marketplace.md index aeaf0878b65..464df80d09c 100644 --- a/versioned_docs/version-8.5/components/modeler/web-modeler/camunda-marketplace.md +++ b/versioned_docs/version-8.5/components/modeler/web-modeler/camunda-marketplace.md @@ -14,6 +14,10 @@ The Camunda Marketplace can be accessed via your [browser](https://marketplace.c ## Visit the Camunda Marketplace +:::note +Connectors created by partners or the community are not part of the commercial Camunda product. Camunda does not support these Connectors as part of its commercial services to enterprise customers. Please evaluate each client to make sure it meets your requirements before using. +::: + To navigate to the Camunda Marketplace, take the following steps: 1. Log in to your Camunda account, and navigate to Web Modeler using the **Camunda components** icon in the top left corner of your console. Click **Modeler**. diff --git a/versioned_docs/version-8.6/components/modeler/web-modeler/camunda-marketplace.md b/versioned_docs/version-8.6/components/modeler/web-modeler/camunda-marketplace.md index 1e366d34ebb..0842066baee 100644 --- a/versioned_docs/version-8.6/components/modeler/web-modeler/camunda-marketplace.md +++ b/versioned_docs/version-8.6/components/modeler/web-modeler/camunda-marketplace.md @@ -12,6 +12,10 @@ If you are a **[Web Modeler Self-Managed](/self-managed/modeler/web-modeler/inst ## Browse Marketplace Connectors +:::note +Connectors created by partners or the community are not part of the commercial Camunda product. Camunda does not support these Connectors as part of its commercial services to enterprise customers. Please evaluate each client to make sure it meets your requirements before using. +::: + To navigate to the Camunda Marketplace, take the following steps: 1. Log in to your Camunda account. From a700c3619a995d9e4614b7b17bf4ea40a3f96e66 Mon Sep 17 00:00:00 2001 From: Aleksander Dytko <102789122+aleksander-dytko@users.noreply.github.com> Date: Mon, 9 Dec 2024 16:42:06 +0100 Subject: [PATCH 8/9] Update bpmn-coverage.md (#4155) * Update bpmn-coverage.md We support Data Object and Data Store in Modeler + for execution. This needs to be reflected in bpmn-coverage * add admonition * backport * revert backport --------- Co-authored-by: Christina Ausley Co-authored-by: christinaausley <84338309+christinaausley@users.noreply.github.com> --- docs/components/modeler/bpmn/bpmn-coverage.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/components/modeler/bpmn/bpmn-coverage.md b/docs/components/modeler/bpmn/bpmn-coverage.md index c96e34cd921..d0e298d1938 100644 --- a/docs/components/modeler/bpmn/bpmn-coverage.md +++ b/docs/components/modeler/bpmn/bpmn-coverage.md @@ -140,15 +140,19 @@ import CompensationSvg from './assets/bpmn-symbols/compensation.svg' ## Data +:::note +`DataObject` and `DataStore`, like other BPMN standard IO mappings, are supported by Camunda for modeling purposes only. +::: + import DataObjectSvg from './assets/bpmn-symbols/data-object.svg' import DataStoreSvg from './assets/bpmn-symbols/data-store.svg' From f2a4047122fcb918cb74df948c3b62480323010f Mon Sep 17 00:00:00 2001 From: DenovVasil Date: Mon, 9 Dec 2024 18:34:43 +0200 Subject: [PATCH 9/9] add gemini documentation (#4676) * add gemini documentation * TW review edits --------- Co-authored-by: mesellings --- .../available-connectors-overview.md | 1 + .../google-gemini.md | 233 ++++++++++++++++++ optimize_sidebars.js | 4 + sidebars.js | 1 + 4 files changed, 239 insertions(+) create mode 100644 docs/components/connectors/out-of-the-box-connectors/google-gemini.md diff --git a/docs/components/connectors/out-of-the-box-connectors/available-connectors-overview.md b/docs/components/connectors/out-of-the-box-connectors/available-connectors-overview.md index 93782940b3e..2f97f2ab95b 100644 --- a/docs/components/connectors/out-of-the-box-connectors/available-connectors-overview.md +++ b/docs/components/connectors/out-of-the-box-connectors/available-connectors-overview.md @@ -47,6 +47,7 @@ import TabItem from "@theme/TabItem"; - [Google Drive Connector](/components/connectors/out-of-the-box-connectors/googledrive.md) - Create folders or files from a [Google Drive](https://www.google.com/drive/) template from your BPMN process. - [Google Maps Platform Connector](/components/connectors/out-of-the-box-connectors/google-maps-platform.md) - Validate addresses, retrieve postal addresses, and calculate distances with [Google Maps Platform Service](https://mapsplatform.google.com/) from your BPMN process - [Google Sheets Connector](/components/connectors/out-of-the-box-connectors/google-sheets.md) - Allows you to work with an existing or new empty spreadsheet on [Google Drive](https://drive.google.com/) from your BPMN process. +- [Google Gemini Connector](/components/connectors/out-of-the-box-connectors/google-gemini.md) - Allows you to work with an existing or new empty spreadsheet on [Google Drive](https://drive.google.com/) from your BPMN process. - [Hugging Face Connector](/components/connectors/out-of-the-box-connectors/hugging-face.md) - Interact with [Hugging Face](https://huggingface.co/) models from your BPMN process. - [Kafka Producer Connector](/components/connectors/out-of-the-box-connectors/kafka.md) - Produce messages to [Kafka](https://kafka.apache.org/) from your BPMN process. - [Microsoft Teams Connector](/components/connectors/out-of-the-box-connectors/microsoft-teams.md) - Interactions with [Microsoft Teams](https://www.microsoft.com/microsoft-teams/) from your BPMN process. diff --git a/docs/components/connectors/out-of-the-box-connectors/google-gemini.md b/docs/components/connectors/out-of-the-box-connectors/google-gemini.md new file mode 100644 index 00000000000..3823a456b0c --- /dev/null +++ b/docs/components/connectors/out-of-the-box-connectors/google-gemini.md @@ -0,0 +1,233 @@ +--- +id: google-gemini +title: Google Gemini Connector +sidebar_label: Google Gemini Connector +description: The Gemini large language models (LLMs) that are used by Gemini for Google Cloud are trained on datasets of publicly available code, Google Cloud-specific material, and other relevant technical information in addition to the datasets used to train the Gemini [foundation models](https://storage.googleapis.com/deepmind-media/gemini/gemini_1_report.pdf). +--- + +:::info +The **Google Gemini Connector** is available for `8.7.0` or later. +::: + +The **Google Gemini Connector** is an outbound Connector that allows you to access Gemini multimodal models from Google. It is capable of understanding virtually any input, and can combine different types of information in a BPMN process. + +## Create a Google Gemini Connector task + +import ConnectorTask from '../../../components/react-components/connector-task.md' + + + +## Make your Google Gemini Connector executable + +To execute this Connector, ensure all mandatory fields are correctly filled. + +:::note +All the mandatory and non-mandatory fields and required settings depending on the operation selection you choose are covered in the upcoming sections. +::: + +## Authentication + +Choose an authentication type from the **Type** dropdown. For details on authentication types, see [Google authentication types](#google-authentication-types). + +## Project ID + +Enter your google cloud project identifier. + +## Region + +Enter the region where your project is located. For example, `us-central1 (lowa)`, `us-west1 (Oregon)`. + +## Model + +Select a model from the dropdown. The following models are currently supported: + +- gemini-1.5-flash-001 +- gemini-1.5-flash-002 +- gemini-1.5-pro-001 +- gemini-1.5-pro-002 +- gemini-1.0-pro-001 +- gemini-1.0-pro-002 +- gemini-1.0-pro-vision-001 + +## Prompt + +Enter a prompt as a FEEL expression, providing text and media. + +- To provide text to Gemini, your expression should contain key _"text"_ and text data. For example, _"text"_ : _"your text"_ +- To provide media to Gemini, your expression should contain key _"mime"_ and mime type text, and key _"uri"_ and media URI. For example, _"mime"_: _"mime type"_, _"uri"_: _"your URI"_. + +For example: + +```feel += [{"text": "who is this video about"}, +{"mime": "video/*", "uri": "https://youtu.be/..."}] +``` + +## System instructions + +Enter system instructions as a string, to determine how the model should respond. + +To learn more about system instructions, refer to [Google system instructions](https://cloud.google.com/vertex-ai/generative-ai/docs/learn/prompts/system-instructions?hl=en). + +## Grounding + +Grounding connects the model output to the verifiable sources of information. + +- This is useful in situations where accuracy and reliability are important. +- To use grounding, select the _Grounding_ checkbox and input the path to the data store. + +To learn more about grounding, refer to [Google grounding overview](https://cloud.google.com/vertex-ai/generative-ai/docs/grounding/overview?hl=en). + +## Safety Filter Settings + +You can adjust the likelihood of receiving a model response which might contain harmful content. + +- Content is blocked based on the probability that it is harmful. +- To use safety filter settings, select the _Safety Filter Settings_ checkbox and select the desired level from dropdown. +- By default, all filters are set to OFF. + +To learn more about safety filters, refer to [Google responsible AI safety filters and settings](https://cloud.google.com/vertex-ai/docs/generative-ai/learn/responsible-ai?hl=en#safety_filters_and_attributes). + +## Add stop sequence + +A stop sequence is a series of characters (including spaces) that stops response generation if encountered by the model. + +The stop sequence should be inserted as a string list. + +For example: + +```feel += ["text 1", "text 2"] +``` + +## Temperature + +The **Temperature** controls the randomness in token selection. + +- A lower temperature is good when you expect a true or correct response. A temperature of `0` means the highest probability token is usually selected. +- A higher temperature can lead to diverse or unexpected results. Some models have a higher temperature max to encourage more random responses. + +## Output token limit + +The **Output token limit** Determines the maximum amount of text output from a single prompt. A token is approximately four characters. + +## Seed + +Setting a **Seed** value is useful if you make repeated requests and want the same model response. + +Deterministic outcome isn’t guaranteed. Changing the model or other settings can cause variations in the response even when you use the same seed value. + +## Top-K + +The **Top-K** specifies the number of candidate tokens when the model is selecting an output token. + +- Use a lower value for less random responses and a higher value for more random responses. +- Only the _gemini-1.0-pro-vision-001_ model supports Top-K. + +## Top-P + +The **Top-P** changes how the model selects tokens for output. + +- Tokens are selected from the most probable to the least probable, until the sum of their probabilities equals the top-p value. +- For example, if tokens A, B, and C have a probability of .3, .2, and .1 and the top-p value is .5, then the model will select either A or B as the next token (using temperature). +- For the least variable results, set top-P to 0. + +## Functional call description + +**Function calling** is a feature of Gemini models that makes it easier to get structured data outputs from generative models. + +- The **Functional call description** must be provided in fell format. +- It is important that all types must be registered with capslock. + +To learn more about function calling, refer to [Google function calling](https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/function-calling). + +For example: + +```fell +[ + { + "name": "get_exchange_rate", + "description":"Get the exchange rate for currencies between countries", + "parameters": { + "type": "OBJECT", + "properties": { + "currency_date": { + "type": "STRING", + "description": "A date that must always be in YYYY-MM-DD format or the value 'latest' if a time period is not specified" + }, + "currency_from": { + "type": "STRING", + "description": "The currency to convert from in ISO 4217 format" + }, + "currency_to": { + "type": "STRING", + "description": "The currency to convert to in ISO 4217 format" + } + }, + "required":[ + "currency_date", + "currency_from", + "currency_to" + ] + } + } +] +``` + +### Google authentication types + +The **Google Gemini Connector** currently supports two methods for authentication and authorization: + +- Based on a short-lived JWT bearer token. +- Based on a refresh token. + +Google supports multiple ways to obtain both types of token. Refer to the [official Google OAuth documentation](https://developers.google.com/identity/protocols/oauth2) for current instructions, or see the examples below. + +#### Example 1: Obtain JWT bearer token with a service account + +:::warning +The following code snippet is for demonstration purposes only and must not be used for real production systems due to security concerns. +For production usage, follow the [official Google guidelines](https://developers.google.com/identity/protocols/oauth2/service-account). +::: + +Assuming you have created a service account and downloaded a JSON file with keys, run the following Python 3 snippet to print the JWT token in the terminal: + +```python +import google.auth +import google.auth.transport.requests +from google.oauth2 import service_account +# Scopes required to execute 'create' endpoind with Google Drive API +SCOPES = ['https://www.googleapis.com/auth/drive', 'https://www.googleapis.com/auth/drive.file', 'https://www.googleapis.com/auth/drive.appdata'] +# File with keys +SERVICE_ACCOUNT_FILE = 'google-service-account-creds.json' +credentials = service_account.Credentials.from_service_account_file(SERVICE_ACCOUNT_FILE, scopes=SCOPES) +auth_req = google.auth.transport.requests.Request() +credentials.refresh(auth_req) +# Print token +print(credentials.token) +``` + +#### Example 2: Obtain bearer and refresh token with OAuth client + +:::warning +The following code snippet is for demonstration purposes only and must not be used for real production systems due to security concerns. +For production usage, follow the [official Google guidelines](https://developers.google.com/identity/protocols/oauth2/web-server). +::: + +Assuming you have created an OAuth client, you can download key files from the Google [Console](https://console.cloud.google.com/apis/credentials). Run the following Python 3 snippet to print the refresh token in the terminal: + +```python +from google_auth_oauthlib.flow import InstalledAppFlow +import pprint + +SCOPES = ['https://www.googleapis.com/auth/drive', 'https://www.googleapis.com/auth/documents'] +OAUTH_KEYS = './oauth-keys.json' # path to your file with OAuth credentials + +def main(): + flow = InstalledAppFlow.from_client_secrets_file(OAUTH_KEYS, SCOPES) + creds = flow.run_local_server(port=54948) + pprint.pprint(vars(creds)) + +if __name__ == "__main__": + main() +``` diff --git a/optimize_sidebars.js b/optimize_sidebars.js index 7a7b5a97f81..da4c8161e46 100644 --- a/optimize_sidebars.js +++ b/optimize_sidebars.js @@ -964,6 +964,10 @@ module.exports = { "Google Sheets Connector", "components/connectors/out-of-the-box-connectors/google-sheets/" ), + docsLink( + "Google Gemini Connector", + "components/connectors/out-of-the-box-connectors/google-gemini/" + ), ], }, diff --git a/sidebars.js b/sidebars.js index c49653ca7d8..14ac338fc90 100644 --- a/sidebars.js +++ b/sidebars.js @@ -339,6 +339,7 @@ module.exports = { "components/connectors/out-of-the-box-connectors/googledrive", "components/connectors/out-of-the-box-connectors/google-maps-platform", "components/connectors/out-of-the-box-connectors/google-sheets", + "components/connectors/out-of-the-box-connectors/google-gemini", ], }, "components/connectors/out-of-the-box-connectors/hugging-face",