You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by "ibek (via GitHub)" <gi...@apache.org> on 2026/03/30 10:54:37 UTC

[PR] CAMEL-23269: Add new component camel-camunda for Camunda 8 [camel]

ibek opened a new pull request, #22338:
URL: https://github.com/apache/camel/pull/22338

   # Description
   
   This PR adds a new **Camunda 8** component, `camel-camunda` (support level: **Preview**), based on the **Camunda Java Client** (`io.camunda:camunda-client-java`).
   
   - **New component**: `components/camel-camunda` with producer + consumer support
     - Producer operations: `startProcess`, `cancelProcess`, `publishMessage`, `completeJob`, `failJob`, `updateJobRetries`, `throwError`, `deployResource`
     - Consumer operation: `worker` (job worker)
   - **Documentation**: new component docs and examples, plus docs site navigation entry
   - **Generated/catalog updates**: component metadata (`camunda.json`), DSL builders (component/endpoint DSL), Camel Main component properties, and related generated resources
   - **Deprecation alignment**: updates `camel-zeebe` metadata/docs to reflect deprecation in favor of `camel-camunda`
   
   # Target
   
   - [x] I checked that the commit is targeting the correct branch (Camel 4 uses the `main` branch)
   
   # Tracking
   
   - [x] If this is a large change, bug fix, or code improvement, I checked there is a [JIRA issue](https://issues.apache.org/jira/browse/CAMEL) filed for the change (usually before you start working on it).
     - https://issues.apache.org/jira/browse/CAMEL-23269
   
   # Apache Camel coding standards and style
   
   - [x] I checked that each commit in the pull request has a meaningful subject line and body.
   
   - [x] I have run `mvn clean install -DskipTests` locally from root folder and I have committed all auto-generated changes.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@camel.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] CAMEL-23269: Add new component camel-camunda for Camunda 8 [camel]

Posted by "apupier (via GitHub)" <gi...@apache.org>.
apupier commented on PR #22338:
URL: https://github.com/apache/camel/pull/22338#issuecomment-4182668365

   Despite review not done again by all initial reviewers. I think all of their blocking reporting issues has been addressed and a specific jira issue has been raised for the remaining ones. Consequently, I merge it.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@camel.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] CAMEL-23269: Add new component camel-camunda for Camunda 8 [camel]

Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on PR #22338:
URL: https://github.com/apache/camel/pull/22338#issuecomment-4163436910

   :white_check_mark: `/component-test camunda` tests passed successfully.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@camel.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] CAMEL-23269: Add new component camel-camunda for Camunda 8 [camel]

Posted by "apupier (via GitHub)" <gi...@apache.org>.
apupier commented on code in PR #22338:
URL: https://github.com/apache/camel/pull/22338#discussion_r3010403363


##########
components/camel-camunda/src/main/java/org/apache/camel/component/camunda/internal/CamundaService.java:
##########
@@ -0,0 +1,267 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.camunda.internal;
+
+import java.time.Duration;
+import java.util.List;
+
+import io.camunda.client.CamundaClient;
+import io.camunda.client.api.command.CreateProcessInstanceCommandStep1;
+import io.camunda.client.api.response.DeploymentEvent;
+import io.camunda.client.api.response.Process;
+import io.camunda.client.api.response.ProcessInstanceEvent;
+import io.camunda.client.api.response.PublishMessageResponse;
+import io.camunda.client.api.worker.JobHandler;
+import io.camunda.client.api.worker.JobWorker;
+import org.apache.camel.component.camunda.model.DeploymentRequest;
+import org.apache.camel.component.camunda.model.DeploymentResponse;
+import org.apache.camel.component.camunda.model.JobRequest;
+import org.apache.camel.component.camunda.model.JobResponse;
+import org.apache.camel.component.camunda.model.MessageRequest;
+import org.apache.camel.component.camunda.model.MessageResponse;
+import org.apache.camel.component.camunda.model.ProcessDeploymentResponse;
+import org.apache.camel.component.camunda.model.ProcessRequest;
+import org.apache.camel.component.camunda.model.ProcessResponse;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CamundaService {
+    private static final Logger LOG = LoggerFactory.getLogger(CamundaService.class);
+
+    private final CamundaClient client;
+
+    public CamundaService(CamundaClient client) {
+        this.client = client;
+    }
+
+    public void doStop() {
+        if (client != null) {
+            client.close();
+        }
+    }
+
+    public ProcessResponse startProcess(ProcessRequest processMessage) {
+        ProcessResponse resultMessage = new ProcessResponse();
+        resultMessage.setProcessId(processMessage.getProcessId());
+
+        try {
+            CreateProcessInstanceCommandStep1.CreateProcessInstanceCommandStep3 step3;
+
+            CreateProcessInstanceCommandStep1.CreateProcessInstanceCommandStep2 step2
+                    = client.newCreateInstanceCommand()
+                            .bpmnProcessId(processMessage.getProcessId());
+
+            if (processMessage.getProcessVersion() > 0) {
+                step3 = step2.version(processMessage.getProcessVersion());
+            } else {
+                step3 = step2.latestVersion();
+            }
+
+            if (!processMessage.getVariables().isEmpty()) {
+                step3.variables(processMessage.getVariables());
+            }
+
+            ProcessInstanceEvent event = step3.send().join();
+
+            resultMessage.setProcessId(event.getBpmnProcessId());
+            resultMessage.setProcessKey(event.getProcessDefinitionKey());
+            resultMessage.setProcessVersion(event.getVersion());
+            resultMessage.setProcessInstanceKey(event.getProcessInstanceKey());
+            resultMessage.setSuccess(true);
+        } catch (Exception exception) {
+            LOG.error("Camunda Error", exception);
+            resultMessage.setProcessVersion(processMessage.getProcessVersion());
+            resultMessage.setErrorMessage(exception.getMessage());
+            resultMessage.setSuccess(false);
+        }
+
+        return resultMessage;
+    }
+
+    public ProcessResponse cancelProcessInstance(ProcessRequest processMessage) {
+        ProcessResponse resultMessage = new ProcessResponse();
+        resultMessage.setProcessInstanceKey(processMessage.getProcessInstanceKey());
+
+        try {
+            client.newCancelInstanceCommand(processMessage.getProcessInstanceKey())
+                    .send()
+                    .join();

Review Comment:
   I think we need to specify a configurable timeout on all the join operations. (can be one timeout for the whole  component) Otherwise we can have pending processes for indefinite time.  But well, maybe it is handled in another way already that I have not found as the camel-zeebe component was doing the same https://github.com/apache/camel/blob/ffbce6a277e44bc2fbff7b1eaeac657484be31f3/components/camel-zeebe/src/main/java/org/apache/camel/component/zeebe/internal/ZeebeService.java#L121
   and not blocking for this PR as this was already like that with zeebe but maybe worth raising an issue for that later on (unless we find how it is configured)



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@camel.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] CAMEL-23269: Add new component camel-camunda for Camunda 8 [camel]

Posted by "ibek (via GitHub)" <gi...@apache.org>.
ibek commented on PR #22338:
URL: https://github.com/apache/camel/pull/22338#issuecomment-4168693232

   /component-test camunda


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@camel.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] CAMEL-23269: Add new component camel-camunda for Camunda 8 [camel]

Posted by "apupier (via GitHub)" <gi...@apache.org>.
apupier commented on PR #22338:
URL: https://github.com/apache/camel/pull/22338#issuecomment-4163567036

   the pr doc validation has failed with:
   
   ```
    [15:06:46.903] ERROR (asciidoctor): target of xref not found: components::camunda-component.adoc
       file: /home/runner/work/camel/camel/camel/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_19.adoc
       source: /home/runner/work/camel/camel/camel (branch: HEAD <worktree> | start path: docs/user-manual)
   [15:06:46.907] ERROR (asciidoctor): target of xref not found: components::camunda-component.adoc
       file: /home/runner/work/camel/camel/camel/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_19.adoc
       source: /home/runner/work/camel/camel/camel (branch: HEAD <worktree> | start path: docs/user-manual)
   [15:07:05.548] WARN (asciidoctor): 
       file: /home/runner/work/camel/camel/camel/docs/components/modules/ROOT/pages/camunda-component.adoc
       source: /home/runner/work/camel/camel/camel (branch: HEAD <worktree> | start path: docs/components)
       msg: {
         "msg": "Target spring-boot:example$json/camunda.json not found",
         "useId": 7,
         "jsonpath": "jsonpathcount$"
       }
   ```
   
   @gansheer is it because it is a new component and the PR job does not handle that o there is a real problem?


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@camel.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] CAMEL-23269: Add new component camel-camunda for Camunda 8 [camel]

Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on PR #22338:
URL: https://github.com/apache/camel/pull/22338#issuecomment-4168709253

   :white_check_mark: `/component-test camunda` tests passed successfully.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@camel.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] CAMEL-23269: Add new component camel-camunda for Camunda 8 [camel]

Posted by "apupier (via GitHub)" <gi...@apache.org>.
apupier commented on code in PR #22338:
URL: https://github.com/apache/camel/pull/22338#discussion_r3010452838


##########
docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_19.adoc:
##########
@@ -560,6 +560,36 @@ The `camel-tracing` and related components (`camel-opentelemetry` and `camel-obs
 
 Some minor difference may be expected when moving to the new components, make sure to read the documentation carefully.
 
+=== camel-zeebe (Deprecation)
+
+The `camel-zeebe` component has been deprecated and will be removed in a future release.
+A new xref:components::camunda-component.adoc[camel-camunda] component has been added as its replacement.
+
+The `camel-camunda` component uses the new Camunda Java Client (`io.camunda:camunda-client-java`)
+instead of the legacy Zeebe client, aligning with the Camunda 8 platform rebranding.
+
+To migrate, change your dependency from:
+
+[source,xml]
+----
+<dependency>
+    <groupId>org.apache.camel</groupId>
+    <artifactId>camel-zeebe</artifactId>
+</dependency>
+----
+
+To:
+
+[source,xml]
+----
+<dependency>
+    <groupId>org.apache.camel</groupId>
+    <artifactId>camel-camunda</artifactId>
+</dependency>
+----
+
+And update your endpoint URIs from `zeebe:` to `camunda:`.
+

Review Comment:
   it also needs to adapt some properties like grpcAddress/restAddress/clusterID
   
   jobType JobKey
   
   these informations are important for people that wants to migrate and also when the upgrade recipes, it is usually looking to the migration notes



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@camel.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] CAMEL-23269: Add new component camel-camunda for Camunda 8 [camel]

Posted by "apupier (via GitHub)" <gi...@apache.org>.
apupier commented on code in PR #22338:
URL: https://github.com/apache/camel/pull/22338#discussion_r3009104017


##########
components/camel-camunda/src/main/docs/camunda-component.adoc:
##########
@@ -0,0 +1,439 @@
+= Camunda Component
+:doctitle: Camunda
+:shortname: camunda
+:artifactid: camel-camunda
+:description: Interact with Camunda 8 Orchestration Clusters using the Camunda Java Client.
+:since: 4.19
+:supportlevel: Preview
+:tabs-sync-option:
+:component-header: Both producer and consumer are supported
+//Manually maintained attributes
+:camel-spring-boot-name: camunda
+
+*Since Camel {since}*
+
+*{component-header}*
+
+The *Camunda* component provides the ability to interact with https://camunda.com/[Camunda 8] process orchestration clusters
+using the https://docs.camunda.io/docs/apis-tools/java-client/[Camunda Java Client].
+
+This component replaces the deprecated xref:zeebe-component.adoc[camel-zeebe] component, which used the older Zeebe Java Client.
+
+[NOTE]
+====
+*Prerequisites*
+
+You must have access to a Camunda 8 cluster. This can be:
+
+* A Camunda SaaS cluster at https://camunda.io/[Camunda SaaS]
+* A self-managed Camunda 8 instance (e.g. via Docker Compose or Kubernetes)
+====
+
+To use the Camunda component, Maven users will need to add the
+following dependency to their `pom.xml`:
+
+[source,xml]
+-----------------------------------------------
+<dependency>
+    <groupId>org.apache.camel</groupId>
+    <artifactId>camel-camunda</artifactId>
+    <version>${camel-version}</version>
+</dependency>
+-----------------------------------------------
+
+== URI format
+
+-------------------------------
+camunda://[endpoint]?[options]
+-------------------------------
+
+
+// component options: START
+include::partial$component-configure-options.adoc[]
+include::partial$component-endpoint-options.adoc[]
+include::partial$component-endpoint-headers.adoc[]
+// component options: END
+
+== Connection Modes
+
+=== Camunda SaaS (Cloud)
+
+Set the `clusterId`, `clientId`, `clientSecret`, and `region` component options.
+
+[source,java]
+----------------------------------------------------------------------------------------------------------------------
+CamundaComponent camunda = context.getComponent("camunda", CamundaComponent.class);
+camunda.setClusterId("your-cluster-id");
+camunda.setClientId("your-client-id");
+camunda.setClientSecret("your-client-secret");
+camunda.setRegion("bru-2");
+----------------------------------------------------------------------------------------------------------------------
+
+=== Self-Managed
+
+Set the `grpcAddress` and `restAddress` component options. For authenticated self-managed clusters,
+also set `clientId`, `clientSecret`, and `oAuthAPI`.
+
+[source,java]
+----------------------------------------------------------------------------------------------------------------------
+CamundaComponent camunda = context.getComponent("camunda", CamundaComponent.class);
+camunda.setGrpcAddress("http://localhost:26500");
+camunda.setRestAddress("http://localhost:8080");
+----------------------------------------------------------------------------------------------------------------------
+
+== Usage
+
+=== Producer Endpoints
+
+[width="100%",cols="10%,90%",options="header",]
+|=======================================================================
+|Endpoint |Description
+
+|`startProcess` |Creates and starts an instance of the specified process.
+
+|`cancelProcess` |Cancels a running process instance.
+
+|`publishMessage` |Publishes a message.
+
+|`completeJob` |Completes a job for a service task.
+
+|`failJob` |Fails a job.
+
+|`updateJobRetries` |Updates the number of retries for a job.
+
+|`throwError` |Throws an error to indicate that a business error has occurred.
+
+|`deployResource` |Deploys a process resource. Currently supports process definitions.
+
+|=======================================================================
+
+The endpoints accept either Java request objects as shown in the examples below or JSON. In JSON, camel case for property names is replaced with all lower case separated by underscores, e.g., processId becomes process_id.
+
+*Examples*
+
+* startProcess
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:start")
+    .process(exchange -> {
+        ProcessRequest request = new ProcessRequest();
+        request.setProcessId("processId");
+        request.setVariables(new HashMap<String,Object> ());
+        exchange.getIn().setBody(request);
+    })
+    .to("camunda://startProcess")
+    .process(exchange -> {
+        ProcessResponse body = exchange.getIn().getBody(ProcessResponse.class);
+        if (body != null) {
+            boolean success = body.isSuccess();
+            long processInstanceKey = body.getProcessInstanceKey();
+        }
+    });
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:start-process
+      steps:
+        - marshal:
+            json: {}
+        - setBody:
+            simple: '{"process_id":"processId","variables":${body}}'
+        - to:
+            uri: "camunda://startProcess"
+----
+====
+
+*JSON Request Example*
+
+[source,json]
+----
+{
+    "process_id" : "Process_0e3ldfm",
+    "variables" : { "v1": "a", "v2": 10 }
+}
+----
+
+*JSON Response Example*
+
+[source,json]
+----
+{
+    "success": true,
+    "process_id": "Process_0e3ldfm",
+    "process_instance_key": 2251799813688297,
+    "process_version": 4,
+    "process_key": 2251799813685906
+}
+----
+
+* cancelProcess
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:cancel")
+    .process(exchange -> {
+        ProcessRequest request = new ProcessRequest();
+        request.setProcessInstanceKey(123);
+        exchange.getIn().setBody(request);
+    })
+    .to("camunda://cancelProcess");
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:cancel
+      steps:
+        - setBody:
+            simple: '{"process_instance_key": 123}'
+        - to:
+            uri: "camunda://cancelProcess"
+----
+====
+
+* publishMessage
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:message")
+    .process(exchange -> {
+        MessageRequest request = new MessageRequest();
+        request.setCorrelationKey("messageKey");
+        request.setTimeToLive(100);
+        request.setVariables(new HashMap<String,Object>());
+        request.setName("MessageName");
+        exchange.getIn().setBody(request);
+    })
+    .to("camunda://publishMessage");
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:message
+      steps:
+        - setBody:
+            simple: '{"name":"MessageName","correlation_key":"messageKey","time_to_live":100,"variables":{}}'
+        - to:
+            uri: "camunda://publishMessage"
+----

Review Comment:
   please add also the xml source example.



##########
components/camel-camunda/src/main/docs/camunda-component.adoc:
##########
@@ -0,0 +1,439 @@
+= Camunda Component
+:doctitle: Camunda
+:shortname: camunda
+:artifactid: camel-camunda
+:description: Interact with Camunda 8 Orchestration Clusters using the Camunda Java Client.
+:since: 4.19
+:supportlevel: Preview
+:tabs-sync-option:
+:component-header: Both producer and consumer are supported
+//Manually maintained attributes
+:camel-spring-boot-name: camunda
+
+*Since Camel {since}*
+
+*{component-header}*
+
+The *Camunda* component provides the ability to interact with https://camunda.com/[Camunda 8] process orchestration clusters
+using the https://docs.camunda.io/docs/apis-tools/java-client/[Camunda Java Client].
+
+This component replaces the deprecated xref:zeebe-component.adoc[camel-zeebe] component, which used the older Zeebe Java Client.
+
+[NOTE]
+====
+*Prerequisites*
+
+You must have access to a Camunda 8 cluster. This can be:
+
+* A Camunda SaaS cluster at https://camunda.io/[Camunda SaaS]
+* A self-managed Camunda 8 instance (e.g. via Docker Compose or Kubernetes)
+====
+
+To use the Camunda component, Maven users will need to add the
+following dependency to their `pom.xml`:
+
+[source,xml]
+-----------------------------------------------
+<dependency>
+    <groupId>org.apache.camel</groupId>
+    <artifactId>camel-camunda</artifactId>
+    <version>${camel-version}</version>
+</dependency>
+-----------------------------------------------
+
+== URI format
+
+-------------------------------
+camunda://[endpoint]?[options]
+-------------------------------
+
+
+// component options: START
+include::partial$component-configure-options.adoc[]
+include::partial$component-endpoint-options.adoc[]
+include::partial$component-endpoint-headers.adoc[]
+// component options: END
+
+== Connection Modes
+
+=== Camunda SaaS (Cloud)
+
+Set the `clusterId`, `clientId`, `clientSecret`, and `region` component options.
+
+[source,java]
+----------------------------------------------------------------------------------------------------------------------
+CamundaComponent camunda = context.getComponent("camunda", CamundaComponent.class);
+camunda.setClusterId("your-cluster-id");
+camunda.setClientId("your-client-id");
+camunda.setClientSecret("your-client-secret");
+camunda.setRegion("bru-2");
+----------------------------------------------------------------------------------------------------------------------
+
+=== Self-Managed
+
+Set the `grpcAddress` and `restAddress` component options. For authenticated self-managed clusters,
+also set `clientId`, `clientSecret`, and `oAuthAPI`.
+
+[source,java]
+----------------------------------------------------------------------------------------------------------------------
+CamundaComponent camunda = context.getComponent("camunda", CamundaComponent.class);
+camunda.setGrpcAddress("http://localhost:26500");
+camunda.setRestAddress("http://localhost:8080");
+----------------------------------------------------------------------------------------------------------------------
+
+== Usage
+
+=== Producer Endpoints
+
+[width="100%",cols="10%,90%",options="header",]
+|=======================================================================
+|Endpoint |Description
+
+|`startProcess` |Creates and starts an instance of the specified process.
+
+|`cancelProcess` |Cancels a running process instance.
+
+|`publishMessage` |Publishes a message.
+
+|`completeJob` |Completes a job for a service task.
+
+|`failJob` |Fails a job.
+
+|`updateJobRetries` |Updates the number of retries for a job.
+
+|`throwError` |Throws an error to indicate that a business error has occurred.
+
+|`deployResource` |Deploys a process resource. Currently supports process definitions.
+
+|=======================================================================
+
+The endpoints accept either Java request objects as shown in the examples below or JSON. In JSON, camel case for property names is replaced with all lower case separated by underscores, e.g., processId becomes process_id.
+
+*Examples*
+
+* startProcess
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:start")
+    .process(exchange -> {
+        ProcessRequest request = new ProcessRequest();
+        request.setProcessId("processId");
+        request.setVariables(new HashMap<String,Object> ());
+        exchange.getIn().setBody(request);
+    })
+    .to("camunda://startProcess")
+    .process(exchange -> {
+        ProcessResponse body = exchange.getIn().getBody(ProcessResponse.class);
+        if (body != null) {
+            boolean success = body.isSuccess();
+            long processInstanceKey = body.getProcessInstanceKey();
+        }
+    });
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:start-process
+      steps:
+        - marshal:
+            json: {}
+        - setBody:
+            simple: '{"process_id":"processId","variables":${body}}'
+        - to:
+            uri: "camunda://startProcess"
+----
+====
+
+*JSON Request Example*
+
+[source,json]
+----
+{
+    "process_id" : "Process_0e3ldfm",
+    "variables" : { "v1": "a", "v2": 10 }
+}
+----
+
+*JSON Response Example*
+
+[source,json]
+----
+{
+    "success": true,
+    "process_id": "Process_0e3ldfm",
+    "process_instance_key": 2251799813688297,
+    "process_version": 4,
+    "process_key": 2251799813685906
+}
+----
+
+* cancelProcess
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:cancel")
+    .process(exchange -> {
+        ProcessRequest request = new ProcessRequest();
+        request.setProcessInstanceKey(123);
+        exchange.getIn().setBody(request);
+    })
+    .to("camunda://cancelProcess");
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:cancel
+      steps:
+        - setBody:
+            simple: '{"process_instance_key": 123}'
+        - to:
+            uri: "camunda://cancelProcess"
+----
+====
+
+* publishMessage
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:message")
+    .process(exchange -> {
+        MessageRequest request = new MessageRequest();
+        request.setCorrelationKey("messageKey");
+        request.setTimeToLive(100);
+        request.setVariables(new HashMap<String,Object>());
+        request.setName("MessageName");
+        exchange.getIn().setBody(request);
+    })
+    .to("camunda://publishMessage");
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:message
+      steps:
+        - setBody:
+            simple: '{"name":"MessageName","correlation_key":"messageKey","time_to_live":100,"variables":{}}'
+        - to:
+            uri: "camunda://publishMessage"
+----
+====
+
+* deployResource
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:deploy")
+    .process(exchange -> {
+        exchange.getIn().setHeader(CamundaConstants.RESOURCE_NAME, "process.bpmn");
+        exchange.getIn().setBody(content.getBytes());
+    })
+    .to("camunda://deployResource");
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:deploy
+      steps:
+        - setHeader:
+            name: CamelCamundaResourceName
+            simple: "process.bpmn"
+        - to:
+            uri: "camunda://deployResource"
+----

Review Comment:
   please add also the xml source example.



##########
components/camel-camunda/src/main/docs/camunda-component.adoc:
##########
@@ -0,0 +1,439 @@
+= Camunda Component
+:doctitle: Camunda
+:shortname: camunda
+:artifactid: camel-camunda
+:description: Interact with Camunda 8 Orchestration Clusters using the Camunda Java Client.
+:since: 4.19
+:supportlevel: Preview
+:tabs-sync-option:
+:component-header: Both producer and consumer are supported
+//Manually maintained attributes
+:camel-spring-boot-name: camunda
+
+*Since Camel {since}*
+
+*{component-header}*
+
+The *Camunda* component provides the ability to interact with https://camunda.com/[Camunda 8] process orchestration clusters
+using the https://docs.camunda.io/docs/apis-tools/java-client/[Camunda Java Client].
+
+This component replaces the deprecated xref:zeebe-component.adoc[camel-zeebe] component, which used the older Zeebe Java Client.
+
+[NOTE]
+====
+*Prerequisites*
+
+You must have access to a Camunda 8 cluster. This can be:
+
+* A Camunda SaaS cluster at https://camunda.io/[Camunda SaaS]
+* A self-managed Camunda 8 instance (e.g. via Docker Compose or Kubernetes)
+====
+
+To use the Camunda component, Maven users will need to add the
+following dependency to their `pom.xml`:
+
+[source,xml]
+-----------------------------------------------
+<dependency>
+    <groupId>org.apache.camel</groupId>
+    <artifactId>camel-camunda</artifactId>
+    <version>${camel-version}</version>
+</dependency>
+-----------------------------------------------
+
+== URI format
+
+-------------------------------
+camunda://[endpoint]?[options]
+-------------------------------
+
+
+// component options: START
+include::partial$component-configure-options.adoc[]
+include::partial$component-endpoint-options.adoc[]
+include::partial$component-endpoint-headers.adoc[]
+// component options: END
+
+== Connection Modes
+
+=== Camunda SaaS (Cloud)
+
+Set the `clusterId`, `clientId`, `clientSecret`, and `region` component options.
+
+[source,java]
+----------------------------------------------------------------------------------------------------------------------
+CamundaComponent camunda = context.getComponent("camunda", CamundaComponent.class);
+camunda.setClusterId("your-cluster-id");
+camunda.setClientId("your-client-id");
+camunda.setClientSecret("your-client-secret");
+camunda.setRegion("bru-2");
+----------------------------------------------------------------------------------------------------------------------
+
+=== Self-Managed
+
+Set the `grpcAddress` and `restAddress` component options. For authenticated self-managed clusters,
+also set `clientId`, `clientSecret`, and `oAuthAPI`.
+
+[source,java]
+----------------------------------------------------------------------------------------------------------------------
+CamundaComponent camunda = context.getComponent("camunda", CamundaComponent.class);
+camunda.setGrpcAddress("http://localhost:26500");
+camunda.setRestAddress("http://localhost:8080");
+----------------------------------------------------------------------------------------------------------------------
+
+== Usage
+
+=== Producer Endpoints
+
+[width="100%",cols="10%,90%",options="header",]
+|=======================================================================
+|Endpoint |Description
+
+|`startProcess` |Creates and starts an instance of the specified process.
+
+|`cancelProcess` |Cancels a running process instance.
+
+|`publishMessage` |Publishes a message.
+
+|`completeJob` |Completes a job for a service task.
+
+|`failJob` |Fails a job.
+
+|`updateJobRetries` |Updates the number of retries for a job.
+
+|`throwError` |Throws an error to indicate that a business error has occurred.
+
+|`deployResource` |Deploys a process resource. Currently supports process definitions.
+
+|=======================================================================
+
+The endpoints accept either Java request objects as shown in the examples below or JSON. In JSON, camel case for property names is replaced with all lower case separated by underscores, e.g., processId becomes process_id.
+
+*Examples*
+
+* startProcess
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:start")
+    .process(exchange -> {
+        ProcessRequest request = new ProcessRequest();
+        request.setProcessId("processId");
+        request.setVariables(new HashMap<String,Object> ());
+        exchange.getIn().setBody(request);
+    })
+    .to("camunda://startProcess")
+    .process(exchange -> {
+        ProcessResponse body = exchange.getIn().getBody(ProcessResponse.class);
+        if (body != null) {
+            boolean success = body.isSuccess();
+            long processInstanceKey = body.getProcessInstanceKey();
+        }
+    });
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:start-process
+      steps:
+        - marshal:
+            json: {}
+        - setBody:
+            simple: '{"process_id":"processId","variables":${body}}'
+        - to:
+            uri: "camunda://startProcess"
+----
+====
+
+*JSON Request Example*
+
+[source,json]
+----
+{
+    "process_id" : "Process_0e3ldfm",
+    "variables" : { "v1": "a", "v2": 10 }
+}
+----
+
+*JSON Response Example*
+
+[source,json]
+----
+{
+    "success": true,
+    "process_id": "Process_0e3ldfm",
+    "process_instance_key": 2251799813688297,
+    "process_version": 4,
+    "process_key": 2251799813685906
+}
+----
+
+* cancelProcess
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:cancel")
+    .process(exchange -> {
+        ProcessRequest request = new ProcessRequest();
+        request.setProcessInstanceKey(123);
+        exchange.getIn().setBody(request);
+    })
+    .to("camunda://cancelProcess");
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:cancel
+      steps:
+        - setBody:
+            simple: '{"process_instance_key": 123}'
+        - to:
+            uri: "camunda://cancelProcess"
+----
+====
+
+* publishMessage
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:message")
+    .process(exchange -> {
+        MessageRequest request = new MessageRequest();
+        request.setCorrelationKey("messageKey");
+        request.setTimeToLive(100);
+        request.setVariables(new HashMap<String,Object>());
+        request.setName("MessageName");
+        exchange.getIn().setBody(request);
+    })
+    .to("camunda://publishMessage");
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:message
+      steps:
+        - setBody:
+            simple: '{"name":"MessageName","correlation_key":"messageKey","time_to_live":100,"variables":{}}'
+        - to:
+            uri: "camunda://publishMessage"
+----
+====
+
+* deployResource
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:deploy")
+    .process(exchange -> {
+        exchange.getIn().setHeader(CamundaConstants.RESOURCE_NAME, "process.bpmn");
+        exchange.getIn().setBody(content.getBytes());
+    })
+    .to("camunda://deployResource");
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:deploy
+      steps:
+        - setHeader:
+            name: CamelCamundaResourceName
+            simple: "process.bpmn"
+        - to:
+            uri: "camunda://deployResource"
+----
+====
+
+=== Consumer Endpoints
+
+[width="100%",cols="10%,90%",options="header",]
+|=======================================================================
+|Endpoint |Description
+
+|worker |Registers a job worker for a job type and provides messages for available jobs.
+
+|=======================================================================
+
+camel-camunda creates a route exchange per job type with a job in the body. The `CamelCamundaJobKey` header is set automatically for each job.
+
+*Example*
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("camunda://worker?jobType=myJobType&timeout=20")
+    .process(exchange -> {
+        JobWorkerMessage body = exchange.getIn().getBody(JobWorkerMessage.class);
+        if (body != null) {
+            long key = body.getKey();
+            String type = body.getType();
+            Map<String,String> customHeaders = body.getCustomHeaders();
+            long processInstanceKey = body.getProcessInstanceKey();
+            String bpmnProcessId = body.getBpmnProcessId();
+            Map<String,Object> variables = body.getVariables();
+        }
+    });
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: "camunda://worker?jobType=myJobType&timeout=20"
+      steps:
+        - log:
+            message: "Received job ${header.CamelCamundaJobKey}"
+----

Review Comment:
   please add also the xml source example.



##########
catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/jbang/camel-jbang-configuration-metadata.json:
##########


Review Comment:
   changes to this file seems unrelated to the PR



##########
components/camel-camunda/src/main/docs/camunda-component.adoc:
##########
@@ -0,0 +1,439 @@
+= Camunda Component
+:doctitle: Camunda
+:shortname: camunda
+:artifactid: camel-camunda
+:description: Interact with Camunda 8 Orchestration Clusters using the Camunda Java Client.
+:since: 4.19
+:supportlevel: Preview
+:tabs-sync-option:
+:component-header: Both producer and consumer are supported
+//Manually maintained attributes
+:camel-spring-boot-name: camunda
+
+*Since Camel {since}*
+
+*{component-header}*
+
+The *Camunda* component provides the ability to interact with https://camunda.com/[Camunda 8] process orchestration clusters
+using the https://docs.camunda.io/docs/apis-tools/java-client/[Camunda Java Client].
+
+This component replaces the deprecated xref:zeebe-component.adoc[camel-zeebe] component, which used the older Zeebe Java Client.
+
+[NOTE]
+====
+*Prerequisites*
+
+You must have access to a Camunda 8 cluster. This can be:
+
+* A Camunda SaaS cluster at https://camunda.io/[Camunda SaaS]
+* A self-managed Camunda 8 instance (e.g. via Docker Compose or Kubernetes)
+====
+
+To use the Camunda component, Maven users will need to add the
+following dependency to their `pom.xml`:
+
+[source,xml]
+-----------------------------------------------
+<dependency>
+    <groupId>org.apache.camel</groupId>
+    <artifactId>camel-camunda</artifactId>
+    <version>${camel-version}</version>
+</dependency>
+-----------------------------------------------
+
+== URI format
+
+-------------------------------
+camunda://[endpoint]?[options]
+-------------------------------
+
+
+// component options: START
+include::partial$component-configure-options.adoc[]
+include::partial$component-endpoint-options.adoc[]
+include::partial$component-endpoint-headers.adoc[]
+// component options: END
+
+== Connection Modes
+
+=== Camunda SaaS (Cloud)
+
+Set the `clusterId`, `clientId`, `clientSecret`, and `region` component options.
+
+[source,java]
+----------------------------------------------------------------------------------------------------------------------
+CamundaComponent camunda = context.getComponent("camunda", CamundaComponent.class);
+camunda.setClusterId("your-cluster-id");
+camunda.setClientId("your-client-id");
+camunda.setClientSecret("your-client-secret");
+camunda.setRegion("bru-2");
+----------------------------------------------------------------------------------------------------------------------
+
+=== Self-Managed
+
+Set the `grpcAddress` and `restAddress` component options. For authenticated self-managed clusters,
+also set `clientId`, `clientSecret`, and `oAuthAPI`.
+
+[source,java]
+----------------------------------------------------------------------------------------------------------------------
+CamundaComponent camunda = context.getComponent("camunda", CamundaComponent.class);
+camunda.setGrpcAddress("http://localhost:26500");
+camunda.setRestAddress("http://localhost:8080");
+----------------------------------------------------------------------------------------------------------------------
+
+== Usage
+
+=== Producer Endpoints
+
+[width="100%",cols="10%,90%",options="header",]
+|=======================================================================
+|Endpoint |Description
+
+|`startProcess` |Creates and starts an instance of the specified process.
+
+|`cancelProcess` |Cancels a running process instance.
+
+|`publishMessage` |Publishes a message.
+
+|`completeJob` |Completes a job for a service task.
+
+|`failJob` |Fails a job.
+
+|`updateJobRetries` |Updates the number of retries for a job.
+
+|`throwError` |Throws an error to indicate that a business error has occurred.
+
+|`deployResource` |Deploys a process resource. Currently supports process definitions.
+
+|=======================================================================
+
+The endpoints accept either Java request objects as shown in the examples below or JSON. In JSON, camel case for property names is replaced with all lower case separated by underscores, e.g., processId becomes process_id.
+
+*Examples*
+
+* startProcess
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:start")
+    .process(exchange -> {
+        ProcessRequest request = new ProcessRequest();
+        request.setProcessId("processId");
+        request.setVariables(new HashMap<String,Object> ());
+        exchange.getIn().setBody(request);
+    })
+    .to("camunda://startProcess")
+    .process(exchange -> {
+        ProcessResponse body = exchange.getIn().getBody(ProcessResponse.class);
+        if (body != null) {
+            boolean success = body.isSuccess();
+            long processInstanceKey = body.getProcessInstanceKey();
+        }
+    });
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:start-process
+      steps:
+        - marshal:
+            json: {}
+        - setBody:
+            simple: '{"process_id":"processId","variables":${body}}'
+        - to:
+            uri: "camunda://startProcess"
+----
+====
+
+*JSON Request Example*
+
+[source,json]
+----
+{
+    "process_id" : "Process_0e3ldfm",
+    "variables" : { "v1": "a", "v2": 10 }
+}
+----
+
+*JSON Response Example*
+
+[source,json]
+----
+{
+    "success": true,
+    "process_id": "Process_0e3ldfm",
+    "process_instance_key": 2251799813688297,
+    "process_version": 4,
+    "process_key": 2251799813685906
+}
+----
+
+* cancelProcess
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:cancel")
+    .process(exchange -> {
+        ProcessRequest request = new ProcessRequest();
+        request.setProcessInstanceKey(123);
+        exchange.getIn().setBody(request);
+    })
+    .to("camunda://cancelProcess");
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:cancel
+      steps:
+        - setBody:
+            simple: '{"process_instance_key": 123}'
+        - to:
+            uri: "camunda://cancelProcess"
+----
+====
+
+* publishMessage
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:message")
+    .process(exchange -> {
+        MessageRequest request = new MessageRequest();
+        request.setCorrelationKey("messageKey");
+        request.setTimeToLive(100);
+        request.setVariables(new HashMap<String,Object>());
+        request.setName("MessageName");
+        exchange.getIn().setBody(request);
+    })
+    .to("camunda://publishMessage");
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:message
+      steps:
+        - setBody:
+            simple: '{"name":"MessageName","correlation_key":"messageKey","time_to_live":100,"variables":{}}'
+        - to:
+            uri: "camunda://publishMessage"
+----
+====
+
+* deployResource
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:deploy")
+    .process(exchange -> {
+        exchange.getIn().setHeader(CamundaConstants.RESOURCE_NAME, "process.bpmn");
+        exchange.getIn().setBody(content.getBytes());
+    })
+    .to("camunda://deployResource");
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:deploy
+      steps:
+        - setHeader:
+            name: CamelCamundaResourceName
+            simple: "process.bpmn"
+        - to:
+            uri: "camunda://deployResource"
+----
+====
+
+=== Consumer Endpoints
+
+[width="100%",cols="10%,90%",options="header",]
+|=======================================================================
+|Endpoint |Description
+
+|worker |Registers a job worker for a job type and provides messages for available jobs.
+
+|=======================================================================
+
+camel-camunda creates a route exchange per job type with a job in the body. The `CamelCamundaJobKey` header is set automatically for each job.
+
+*Example*
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("camunda://worker?jobType=myJobType&timeout=20")
+    .process(exchange -> {
+        JobWorkerMessage body = exchange.getIn().getBody(JobWorkerMessage.class);
+        if (body != null) {
+            long key = body.getKey();
+            String type = body.getType();
+            Map<String,String> customHeaders = body.getCustomHeaders();
+            long processInstanceKey = body.getProcessInstanceKey();
+            String bpmnProcessId = body.getBpmnProcessId();
+            Map<String,Object> variables = body.getVariables();
+        }
+    });
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: "camunda://worker?jobType=myJobType&timeout=20"
+      steps:
+        - log:
+            message: "Received job ${header.CamelCamundaJobKey}"
+----
+====
+
+[[Worker_Flow_Examples]]
+==== Worker Flow Examples
+
+The `completeJob`, `failJob`, and `throwError` producer endpoints are designed to work with the `worker` consumer. The consumer automatically sets the `CamelCamundaJobKey` header, so these operations pick it up without any manual configuration.
+
+* *Complete a job* — processes the job and completes it, optionally passing output variables as a Map body:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("camunda://worker?jobType=myJobType&timeout=20")
+    .process(exchange -> {
+        Map<String, Object> result = new HashMap<>();
+        result.put("approved", true);
+        exchange.getIn().setBody(result);
+    })
+    .to("camunda://completeJob");
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: "camunda://worker?jobType=myJobType&timeout=20"
+      steps:
+        - log:
+            message: "Processing job ${header.CamelCamundaJobKey}"
+        - to:
+            uri: "camunda://completeJob"
+----
+====
+
+* *Fail a job* — reports a job failure with an error message:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("camunda://worker?jobType=myJobType&timeout=20")
+    .process(exchange -> {
+        exchange.getIn().setHeader(CamundaConstants.ERROR_MESSAGE, "Processing failed");
+    })
+    .to("camunda://failJob");
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: "camunda://worker?jobType=myJobType&timeout=20"
+      steps:
+        - setHeader:
+            name: CamelCamundaErrorMessage
+            simple: "Processing failed"
+        - to:
+            uri: "camunda://failJob"
+----
+====
+
+* *Throw a business error* — signals a business error with an error code and message:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("camunda://worker?jobType=myJobType&timeout=20")
+    .process(exchange -> {
+        exchange.getIn().setHeader(CamundaConstants.ERROR_CODE, "INVALID_DATA");
+        exchange.getIn().setHeader(CamundaConstants.ERROR_MESSAGE, "Data validation failed");
+    })
+    .to("camunda://throwError");
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: "camunda://worker?jobType=myJobType&timeout=20"
+      steps:
+        - setHeader:
+            name: CamelCamundaErrorCode
+            simple: "INVALID_DATA"
+        - setHeader:
+            name: CamelCamundaErrorMessage
+            simple: "Data validation failed"
+        - to:
+            uri: "camunda://throwError"
+----

Review Comment:
   please add also the xml source example.



##########
components/camel-camunda/src/main/docs/camunda-component.adoc:
##########
@@ -0,0 +1,439 @@
+= Camunda Component
+:doctitle: Camunda
+:shortname: camunda
+:artifactid: camel-camunda
+:description: Interact with Camunda 8 Orchestration Clusters using the Camunda Java Client.
+:since: 4.19
+:supportlevel: Preview
+:tabs-sync-option:
+:component-header: Both producer and consumer are supported
+//Manually maintained attributes
+:camel-spring-boot-name: camunda
+
+*Since Camel {since}*
+
+*{component-header}*
+
+The *Camunda* component provides the ability to interact with https://camunda.com/[Camunda 8] process orchestration clusters
+using the https://docs.camunda.io/docs/apis-tools/java-client/[Camunda Java Client].
+
+This component replaces the deprecated xref:zeebe-component.adoc[camel-zeebe] component, which used the older Zeebe Java Client.
+
+[NOTE]
+====
+*Prerequisites*
+
+You must have access to a Camunda 8 cluster. This can be:
+
+* A Camunda SaaS cluster at https://camunda.io/[Camunda SaaS]
+* A self-managed Camunda 8 instance (e.g. via Docker Compose or Kubernetes)
+====
+
+To use the Camunda component, Maven users will need to add the
+following dependency to their `pom.xml`:
+
+[source,xml]
+-----------------------------------------------
+<dependency>
+    <groupId>org.apache.camel</groupId>
+    <artifactId>camel-camunda</artifactId>
+    <version>${camel-version}</version>
+</dependency>
+-----------------------------------------------
+
+== URI format
+
+-------------------------------
+camunda://[endpoint]?[options]
+-------------------------------
+
+
+// component options: START
+include::partial$component-configure-options.adoc[]
+include::partial$component-endpoint-options.adoc[]
+include::partial$component-endpoint-headers.adoc[]
+// component options: END
+
+== Connection Modes
+
+=== Camunda SaaS (Cloud)
+
+Set the `clusterId`, `clientId`, `clientSecret`, and `region` component options.
+
+[source,java]
+----------------------------------------------------------------------------------------------------------------------
+CamundaComponent camunda = context.getComponent("camunda", CamundaComponent.class);
+camunda.setClusterId("your-cluster-id");
+camunda.setClientId("your-client-id");
+camunda.setClientSecret("your-client-secret");
+camunda.setRegion("bru-2");
+----------------------------------------------------------------------------------------------------------------------
+
+=== Self-Managed
+
+Set the `grpcAddress` and `restAddress` component options. For authenticated self-managed clusters,
+also set `clientId`, `clientSecret`, and `oAuthAPI`.
+
+[source,java]
+----------------------------------------------------------------------------------------------------------------------
+CamundaComponent camunda = context.getComponent("camunda", CamundaComponent.class);
+camunda.setGrpcAddress("http://localhost:26500");
+camunda.setRestAddress("http://localhost:8080");
+----------------------------------------------------------------------------------------------------------------------
+
+== Usage
+
+=== Producer Endpoints
+
+[width="100%",cols="10%,90%",options="header",]
+|=======================================================================
+|Endpoint |Description
+
+|`startProcess` |Creates and starts an instance of the specified process.
+
+|`cancelProcess` |Cancels a running process instance.
+
+|`publishMessage` |Publishes a message.
+
+|`completeJob` |Completes a job for a service task.
+
+|`failJob` |Fails a job.
+
+|`updateJobRetries` |Updates the number of retries for a job.
+
+|`throwError` |Throws an error to indicate that a business error has occurred.
+
+|`deployResource` |Deploys a process resource. Currently supports process definitions.
+
+|=======================================================================
+
+The endpoints accept either Java request objects as shown in the examples below or JSON. In JSON, camel case for property names is replaced with all lower case separated by underscores, e.g., processId becomes process_id.
+
+*Examples*
+
+* startProcess
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:start")
+    .process(exchange -> {
+        ProcessRequest request = new ProcessRequest();
+        request.setProcessId("processId");
+        request.setVariables(new HashMap<String,Object> ());
+        exchange.getIn().setBody(request);
+    })
+    .to("camunda://startProcess")
+    .process(exchange -> {
+        ProcessResponse body = exchange.getIn().getBody(ProcessResponse.class);
+        if (body != null) {
+            boolean success = body.isSuccess();
+            long processInstanceKey = body.getProcessInstanceKey();
+        }
+    });
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:start-process
+      steps:
+        - marshal:
+            json: {}
+        - setBody:
+            simple: '{"process_id":"processId","variables":${body}}'
+        - to:
+            uri: "camunda://startProcess"
+----
+====
+
+*JSON Request Example*
+
+[source,json]
+----
+{
+    "process_id" : "Process_0e3ldfm",
+    "variables" : { "v1": "a", "v2": 10 }
+}
+----
+
+*JSON Response Example*
+
+[source,json]
+----
+{
+    "success": true,
+    "process_id": "Process_0e3ldfm",
+    "process_instance_key": 2251799813688297,
+    "process_version": 4,
+    "process_key": 2251799813685906
+}
+----
+
+* cancelProcess
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:cancel")
+    .process(exchange -> {
+        ProcessRequest request = new ProcessRequest();
+        request.setProcessInstanceKey(123);
+        exchange.getIn().setBody(request);
+    })
+    .to("camunda://cancelProcess");
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:cancel
+      steps:
+        - setBody:
+            simple: '{"process_instance_key": 123}'
+        - to:
+            uri: "camunda://cancelProcess"
+----
+====

Review Comment:
   please add also the xml source example.



##########
components/camel-camunda/src/main/docs/camunda-component.adoc:
##########
@@ -0,0 +1,439 @@
+= Camunda Component
+:doctitle: Camunda
+:shortname: camunda
+:artifactid: camel-camunda
+:description: Interact with Camunda 8 Orchestration Clusters using the Camunda Java Client.
+:since: 4.19
+:supportlevel: Preview
+:tabs-sync-option:
+:component-header: Both producer and consumer are supported
+//Manually maintained attributes
+:camel-spring-boot-name: camunda
+
+*Since Camel {since}*
+
+*{component-header}*
+
+The *Camunda* component provides the ability to interact with https://camunda.com/[Camunda 8] process orchestration clusters
+using the https://docs.camunda.io/docs/apis-tools/java-client/[Camunda Java Client].
+
+This component replaces the deprecated xref:zeebe-component.adoc[camel-zeebe] component, which used the older Zeebe Java Client.
+
+[NOTE]
+====
+*Prerequisites*
+
+You must have access to a Camunda 8 cluster. This can be:
+
+* A Camunda SaaS cluster at https://camunda.io/[Camunda SaaS]
+* A self-managed Camunda 8 instance (e.g. via Docker Compose or Kubernetes)
+====
+
+To use the Camunda component, Maven users will need to add the
+following dependency to their `pom.xml`:
+
+[source,xml]
+-----------------------------------------------
+<dependency>
+    <groupId>org.apache.camel</groupId>
+    <artifactId>camel-camunda</artifactId>
+    <version>${camel-version}</version>
+</dependency>
+-----------------------------------------------
+
+== URI format
+
+-------------------------------
+camunda://[endpoint]?[options]
+-------------------------------
+
+
+// component options: START
+include::partial$component-configure-options.adoc[]
+include::partial$component-endpoint-options.adoc[]
+include::partial$component-endpoint-headers.adoc[]
+// component options: END
+
+== Connection Modes
+
+=== Camunda SaaS (Cloud)
+
+Set the `clusterId`, `clientId`, `clientSecret`, and `region` component options.
+
+[source,java]
+----------------------------------------------------------------------------------------------------------------------
+CamundaComponent camunda = context.getComponent("camunda", CamundaComponent.class);
+camunda.setClusterId("your-cluster-id");
+camunda.setClientId("your-client-id");
+camunda.setClientSecret("your-client-secret");
+camunda.setRegion("bru-2");
+----------------------------------------------------------------------------------------------------------------------
+
+=== Self-Managed
+
+Set the `grpcAddress` and `restAddress` component options. For authenticated self-managed clusters,
+also set `clientId`, `clientSecret`, and `oAuthAPI`.
+
+[source,java]
+----------------------------------------------------------------------------------------------------------------------
+CamundaComponent camunda = context.getComponent("camunda", CamundaComponent.class);
+camunda.setGrpcAddress("http://localhost:26500");
+camunda.setRestAddress("http://localhost:8080");
+----------------------------------------------------------------------------------------------------------------------
+
+== Usage
+
+=== Producer Endpoints
+
+[width="100%",cols="10%,90%",options="header",]
+|=======================================================================
+|Endpoint |Description
+
+|`startProcess` |Creates and starts an instance of the specified process.
+
+|`cancelProcess` |Cancels a running process instance.
+
+|`publishMessage` |Publishes a message.
+
+|`completeJob` |Completes a job for a service task.
+
+|`failJob` |Fails a job.
+
+|`updateJobRetries` |Updates the number of retries for a job.
+
+|`throwError` |Throws an error to indicate that a business error has occurred.
+
+|`deployResource` |Deploys a process resource. Currently supports process definitions.
+
+|=======================================================================
+
+The endpoints accept either Java request objects as shown in the examples below or JSON. In JSON, camel case for property names is replaced with all lower case separated by underscores, e.g., processId becomes process_id.
+
+*Examples*
+
+* startProcess
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:start")
+    .process(exchange -> {
+        ProcessRequest request = new ProcessRequest();
+        request.setProcessId("processId");
+        request.setVariables(new HashMap<String,Object> ());
+        exchange.getIn().setBody(request);
+    })
+    .to("camunda://startProcess")
+    .process(exchange -> {
+        ProcessResponse body = exchange.getIn().getBody(ProcessResponse.class);
+        if (body != null) {
+            boolean success = body.isSuccess();
+            long processInstanceKey = body.getProcessInstanceKey();
+        }
+    });
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:start-process
+      steps:
+        - marshal:
+            json: {}
+        - setBody:
+            simple: '{"process_id":"processId","variables":${body}}'
+        - to:
+            uri: "camunda://startProcess"
+----
+====
+
+*JSON Request Example*
+
+[source,json]
+----
+{
+    "process_id" : "Process_0e3ldfm",
+    "variables" : { "v1": "a", "v2": 10 }
+}
+----
+
+*JSON Response Example*
+
+[source,json]
+----
+{
+    "success": true,
+    "process_id": "Process_0e3ldfm",
+    "process_instance_key": 2251799813688297,
+    "process_version": 4,
+    "process_key": 2251799813685906
+}
+----
+
+* cancelProcess
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:cancel")
+    .process(exchange -> {
+        ProcessRequest request = new ProcessRequest();
+        request.setProcessInstanceKey(123);
+        exchange.getIn().setBody(request);
+    })
+    .to("camunda://cancelProcess");
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:cancel
+      steps:
+        - setBody:
+            simple: '{"process_instance_key": 123}'
+        - to:
+            uri: "camunda://cancelProcess"
+----
+====
+
+* publishMessage
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:message")
+    .process(exchange -> {
+        MessageRequest request = new MessageRequest();
+        request.setCorrelationKey("messageKey");
+        request.setTimeToLive(100);
+        request.setVariables(new HashMap<String,Object>());
+        request.setName("MessageName");
+        exchange.getIn().setBody(request);
+    })
+    .to("camunda://publishMessage");
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:message
+      steps:
+        - setBody:
+            simple: '{"name":"MessageName","correlation_key":"messageKey","time_to_live":100,"variables":{}}'
+        - to:
+            uri: "camunda://publishMessage"
+----
+====
+
+* deployResource
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:deploy")
+    .process(exchange -> {
+        exchange.getIn().setHeader(CamundaConstants.RESOURCE_NAME, "process.bpmn");
+        exchange.getIn().setBody(content.getBytes());
+    })
+    .to("camunda://deployResource");
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:deploy
+      steps:
+        - setHeader:
+            name: CamelCamundaResourceName
+            simple: "process.bpmn"
+        - to:
+            uri: "camunda://deployResource"
+----
+====
+
+=== Consumer Endpoints
+
+[width="100%",cols="10%,90%",options="header",]
+|=======================================================================
+|Endpoint |Description
+
+|worker |Registers a job worker for a job type and provides messages for available jobs.
+
+|=======================================================================
+
+camel-camunda creates a route exchange per job type with a job in the body. The `CamelCamundaJobKey` header is set automatically for each job.
+
+*Example*
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("camunda://worker?jobType=myJobType&timeout=20")
+    .process(exchange -> {
+        JobWorkerMessage body = exchange.getIn().getBody(JobWorkerMessage.class);
+        if (body != null) {
+            long key = body.getKey();
+            String type = body.getType();
+            Map<String,String> customHeaders = body.getCustomHeaders();
+            long processInstanceKey = body.getProcessInstanceKey();
+            String bpmnProcessId = body.getBpmnProcessId();
+            Map<String,Object> variables = body.getVariables();
+        }
+    });
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: "camunda://worker?jobType=myJobType&timeout=20"
+      steps:
+        - log:
+            message: "Received job ${header.CamelCamundaJobKey}"
+----
+====
+
+[[Worker_Flow_Examples]]
+==== Worker Flow Examples
+
+The `completeJob`, `failJob`, and `throwError` producer endpoints are designed to work with the `worker` consumer. The consumer automatically sets the `CamelCamundaJobKey` header, so these operations pick it up without any manual configuration.
+
+* *Complete a job* — processes the job and completes it, optionally passing output variables as a Map body:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("camunda://worker?jobType=myJobType&timeout=20")
+    .process(exchange -> {
+        Map<String, Object> result = new HashMap<>();
+        result.put("approved", true);
+        exchange.getIn().setBody(result);
+    })
+    .to("camunda://completeJob");
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: "camunda://worker?jobType=myJobType&timeout=20"
+      steps:
+        - log:
+            message: "Processing job ${header.CamelCamundaJobKey}"
+        - to:
+            uri: "camunda://completeJob"
+----
+====
+
+* *Fail a job* — reports a job failure with an error message:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("camunda://worker?jobType=myJobType&timeout=20")
+    .process(exchange -> {
+        exchange.getIn().setHeader(CamundaConstants.ERROR_MESSAGE, "Processing failed");
+    })
+    .to("camunda://failJob");
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: "camunda://worker?jobType=myJobType&timeout=20"
+      steps:
+        - setHeader:
+            name: CamelCamundaErrorMessage
+            simple: "Processing failed"
+        - to:
+            uri: "camunda://failJob"
+----
+====

Review Comment:
   please add also the xml source example.



##########
components/camel-camunda/src/main/docs/camunda-component.adoc:
##########
@@ -0,0 +1,439 @@
+= Camunda Component
+:doctitle: Camunda
+:shortname: camunda
+:artifactid: camel-camunda
+:description: Interact with Camunda 8 Orchestration Clusters using the Camunda Java Client.
+:since: 4.19
+:supportlevel: Preview
+:tabs-sync-option:
+:component-header: Both producer and consumer are supported
+//Manually maintained attributes
+:camel-spring-boot-name: camunda
+
+*Since Camel {since}*
+
+*{component-header}*
+
+The *Camunda* component provides the ability to interact with https://camunda.com/[Camunda 8] process orchestration clusters
+using the https://docs.camunda.io/docs/apis-tools/java-client/[Camunda Java Client].
+
+This component replaces the deprecated xref:zeebe-component.adoc[camel-zeebe] component, which used the older Zeebe Java Client.
+
+[NOTE]
+====
+*Prerequisites*
+
+You must have access to a Camunda 8 cluster. This can be:
+
+* A Camunda SaaS cluster at https://camunda.io/[Camunda SaaS]
+* A self-managed Camunda 8 instance (e.g. via Docker Compose or Kubernetes)
+====
+
+To use the Camunda component, Maven users will need to add the
+following dependency to their `pom.xml`:
+
+[source,xml]
+-----------------------------------------------
+<dependency>
+    <groupId>org.apache.camel</groupId>
+    <artifactId>camel-camunda</artifactId>
+    <version>${camel-version}</version>
+</dependency>
+-----------------------------------------------
+
+== URI format
+
+-------------------------------
+camunda://[endpoint]?[options]
+-------------------------------
+
+
+// component options: START
+include::partial$component-configure-options.adoc[]
+include::partial$component-endpoint-options.adoc[]
+include::partial$component-endpoint-headers.adoc[]
+// component options: END
+
+== Connection Modes
+
+=== Camunda SaaS (Cloud)
+
+Set the `clusterId`, `clientId`, `clientSecret`, and `region` component options.
+
+[source,java]
+----------------------------------------------------------------------------------------------------------------------
+CamundaComponent camunda = context.getComponent("camunda", CamundaComponent.class);
+camunda.setClusterId("your-cluster-id");
+camunda.setClientId("your-client-id");
+camunda.setClientSecret("your-client-secret");
+camunda.setRegion("bru-2");
+----------------------------------------------------------------------------------------------------------------------
+
+=== Self-Managed
+
+Set the `grpcAddress` and `restAddress` component options. For authenticated self-managed clusters,
+also set `clientId`, `clientSecret`, and `oAuthAPI`.
+
+[source,java]
+----------------------------------------------------------------------------------------------------------------------
+CamundaComponent camunda = context.getComponent("camunda", CamundaComponent.class);
+camunda.setGrpcAddress("http://localhost:26500");
+camunda.setRestAddress("http://localhost:8080");
+----------------------------------------------------------------------------------------------------------------------
+
+== Usage
+
+=== Producer Endpoints
+
+[width="100%",cols="10%,90%",options="header",]
+|=======================================================================
+|Endpoint |Description
+
+|`startProcess` |Creates and starts an instance of the specified process.
+
+|`cancelProcess` |Cancels a running process instance.
+
+|`publishMessage` |Publishes a message.
+
+|`completeJob` |Completes a job for a service task.
+
+|`failJob` |Fails a job.
+
+|`updateJobRetries` |Updates the number of retries for a job.
+
+|`throwError` |Throws an error to indicate that a business error has occurred.
+
+|`deployResource` |Deploys a process resource. Currently supports process definitions.
+
+|=======================================================================
+
+The endpoints accept either Java request objects as shown in the examples below or JSON. In JSON, camel case for property names is replaced with all lower case separated by underscores, e.g., processId becomes process_id.
+
+*Examples*
+
+* startProcess
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:start")
+    .process(exchange -> {
+        ProcessRequest request = new ProcessRequest();
+        request.setProcessId("processId");
+        request.setVariables(new HashMap<String,Object> ());
+        exchange.getIn().setBody(request);
+    })
+    .to("camunda://startProcess")
+    .process(exchange -> {
+        ProcessResponse body = exchange.getIn().getBody(ProcessResponse.class);
+        if (body != null) {
+            boolean success = body.isSuccess();
+            long processInstanceKey = body.getProcessInstanceKey();
+        }
+    });
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:start-process
+      steps:
+        - marshal:
+            json: {}
+        - setBody:
+            simple: '{"process_id":"processId","variables":${body}}'
+        - to:
+            uri: "camunda://startProcess"
+----
+====
+
+*JSON Request Example*
+
+[source,json]
+----
+{
+    "process_id" : "Process_0e3ldfm",
+    "variables" : { "v1": "a", "v2": 10 }
+}
+----
+
+*JSON Response Example*
+
+[source,json]
+----
+{
+    "success": true,
+    "process_id": "Process_0e3ldfm",
+    "process_instance_key": 2251799813688297,
+    "process_version": 4,
+    "process_key": 2251799813685906
+}
+----
+
+* cancelProcess
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:cancel")
+    .process(exchange -> {
+        ProcessRequest request = new ProcessRequest();
+        request.setProcessInstanceKey(123);
+        exchange.getIn().setBody(request);
+    })
+    .to("camunda://cancelProcess");
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:cancel
+      steps:
+        - setBody:
+            simple: '{"process_instance_key": 123}'
+        - to:
+            uri: "camunda://cancelProcess"
+----
+====
+
+* publishMessage
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:message")
+    .process(exchange -> {
+        MessageRequest request = new MessageRequest();
+        request.setCorrelationKey("messageKey");
+        request.setTimeToLive(100);
+        request.setVariables(new HashMap<String,Object>());
+        request.setName("MessageName");
+        exchange.getIn().setBody(request);
+    })
+    .to("camunda://publishMessage");
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:message
+      steps:
+        - setBody:
+            simple: '{"name":"MessageName","correlation_key":"messageKey","time_to_live":100,"variables":{}}'
+        - to:
+            uri: "camunda://publishMessage"
+----
+====
+
+* deployResource
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:deploy")
+    .process(exchange -> {
+        exchange.getIn().setHeader(CamundaConstants.RESOURCE_NAME, "process.bpmn");
+        exchange.getIn().setBody(content.getBytes());
+    })
+    .to("camunda://deployResource");
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:deploy
+      steps:
+        - setHeader:
+            name: CamelCamundaResourceName
+            simple: "process.bpmn"
+        - to:
+            uri: "camunda://deployResource"
+----
+====
+
+=== Consumer Endpoints
+
+[width="100%",cols="10%,90%",options="header",]
+|=======================================================================
+|Endpoint |Description
+
+|worker |Registers a job worker for a job type and provides messages for available jobs.
+
+|=======================================================================
+
+camel-camunda creates a route exchange per job type with a job in the body. The `CamelCamundaJobKey` header is set automatically for each job.
+
+*Example*
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("camunda://worker?jobType=myJobType&timeout=20")
+    .process(exchange -> {
+        JobWorkerMessage body = exchange.getIn().getBody(JobWorkerMessage.class);
+        if (body != null) {
+            long key = body.getKey();
+            String type = body.getType();
+            Map<String,String> customHeaders = body.getCustomHeaders();
+            long processInstanceKey = body.getProcessInstanceKey();
+            String bpmnProcessId = body.getBpmnProcessId();
+            Map<String,Object> variables = body.getVariables();
+        }
+    });
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: "camunda://worker?jobType=myJobType&timeout=20"
+      steps:
+        - log:
+            message: "Received job ${header.CamelCamundaJobKey}"
+----
+====
+
+[[Worker_Flow_Examples]]
+==== Worker Flow Examples
+
+The `completeJob`, `failJob`, and `throwError` producer endpoints are designed to work with the `worker` consumer. The consumer automatically sets the `CamelCamundaJobKey` header, so these operations pick it up without any manual configuration.
+
+* *Complete a job* — processes the job and completes it, optionally passing output variables as a Map body:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("camunda://worker?jobType=myJobType&timeout=20")
+    .process(exchange -> {
+        Map<String, Object> result = new HashMap<>();
+        result.put("approved", true);
+        exchange.getIn().setBody(result);
+    })
+    .to("camunda://completeJob");
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: "camunda://worker?jobType=myJobType&timeout=20"
+      steps:
+        - log:
+            message: "Processing job ${header.CamelCamundaJobKey}"
+        - to:
+            uri: "camunda://completeJob"
+----
+====

Review Comment:
   please add also the xml source example.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@camel.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] CAMEL-23269: Add new component camel-camunda for Camunda 8 [camel]

Posted by "ibek (via GitHub)" <gi...@apache.org>.
ibek commented on PR #22338:
URL: https://github.com/apache/camel/pull/22338#issuecomment-4168692792

   Thank you @apupier , I removed those links then


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@camel.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] CAMEL-23269: Add new component camel-camunda for Camunda 8 [camel]

Posted by "apupier (via GitHub)" <gi...@apache.org>.
apupier commented on PR #22338:
URL: https://github.com/apache/camel/pull/22338#issuecomment-4154131941

   more explanation on the context: Zeebe is deprecated https://roadmap.camunda.com/c/271-deprecate-zeebe-clients , the replacement is camunda java clients. This PR is both deprecating camel-zeebe and adding camel-camunda


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@camel.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] CAMEL-23269: Add new component camel-camunda for Camunda 8 [camel]

Posted by "ibek (via GitHub)" <gi...@apache.org>.
ibek commented on PR #22338:
URL: https://github.com/apache/camel/pull/22338#issuecomment-4161292268

   Thank you all. Many of the suggestions / improvements were done in the last commit.
   
   The additional improvements and provided suggestions would be implemented as part of: https://issues.apache.org/jira/browse/CAMEL-23275
   
   I would like this PREVIEW component to be merged soonish for an upcoming university lessons (not meant for production use) - it already does what I need it for: https://github.com/ibek/pv207-camel-lab/tree/main


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@camel.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] CAMEL-23269: Add new component camel-camunda for Camunda 8 [camel]

Posted by "apupier (via GitHub)" <gi...@apache.org>.
apupier commented on PR #22338:
URL: https://github.com/apache/camel/pull/22338#issuecomment-4163183825

   tips: do not forget to `re-request review` when you like another round of review and feedback were addressed/discussed/rejected so that it becomes visible to the dashboards of the reviewers


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@camel.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] CAMEL-23269: Add new component camel-camunda for Camunda 8 [camel]

Posted by "apupier (via GitHub)" <gi...@apache.org>.
apupier commented on PR #22338:
URL: https://github.com/apache/camel/pull/22338#issuecomment-4163331261

   /component-test camunda


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@camel.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] CAMEL-23269: Add new component camel-camunda for Camunda 8 [camel]

Posted by "apupier (via GitHub)" <gi...@apache.org>.
apupier commented on PR #22338:
URL: https://github.com/apache/camel/pull/22338#issuecomment-4155579778

   > AFAIK we didn't even have integration tests in camel-zeebe so did at least the mocks like there.
   
   there are Integration tests, even if unfortunately they require to be launched locally and access an instance of Camunda. For instance https://github.com/apache/camel/blob/main/components/camel-zeebe/src/test/java/org/apache/camel/component/zeebe/ZeebeConsumerIT.java
   
   If not done within this PR, please report an issue in JIRA to implement that with TestContainer


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@camel.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] CAMEL-23269: Add new component camel-camunda for Camunda 8 [camel]

Posted by "gnodet (via GitHub)" <gi...@apache.org>.
gnodet commented on code in PR #22338:
URL: https://github.com/apache/camel/pull/22338#discussion_r3010398952


##########
components/camel-camunda/src/main/java/org/apache/camel/component/camunda/CamundaComponent.java:
##########
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.camunda;
+
+import java.net.URI;
+import java.util.Map;
+
+import io.camunda.client.CamundaClient;
+import io.camunda.client.CamundaClientBuilder;
+import org.apache.camel.Endpoint;
+import org.apache.camel.component.camunda.internal.CamundaService;
+import org.apache.camel.component.camunda.internal.OperationName;
+import org.apache.camel.spi.Metadata;
+import org.apache.camel.support.DefaultComponent;
+
+@org.apache.camel.spi.annotations.Component("camunda")
+public class CamundaComponent extends DefaultComponent {
+
+    @Metadata(label = "security", description = "Camunda SaaS cluster ID. When set, the client connects via the cloud builder.")
+    String clusterId;
+
+    @Metadata(label = "security", description = "Camunda SaaS region (default: bru-2).", defaultValue = "bru-2")
+    String region = "bru-2";
+
+    @Metadata(label = "security", secret = true,
+              description = "Client ID for OAuth / SaaS authentication.")
+    String clientId;
+
+    @Metadata(label = "security", secret = true,
+              description = "Client secret for OAuth / SaaS authentication.")
+    String clientSecret;
+
+    @Metadata(label = "common",
+              description = "gRPC address of the Camunda cluster (e.g. http://localhost:26500). "
+                            + "Used for self-managed connections when clusterId is not set.",
+              defaultValue = "http://localhost:26500")
+    String grpcAddress = "http://localhost:26500";
+
+    @Metadata(label = "common",
+              description = "REST address of the Camunda cluster (e.g. http://localhost:8080). "
+                            + "Used for self-managed connections when clusterId is not set.",
+              defaultValue = "http://localhost:8080")
+    String restAddress = "http://localhost:8080";
+
+    @Metadata(label = "security",
+              description = "OAuth authorization server URL for self-managed authentication.")
+    String oAuthAPI;
+
+    private CamundaService camundaService;
+
+    protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
+        OperationName operationName = OperationName.fromValue(remaining);
+
+        Endpoint endpoint = new CamundaEndpoint(uri, this, operationName);
+        setProperties(endpoint, parameters);
+        return endpoint;
+    }
+
+    public CamundaService getCamundaService() {
+        return camundaService;
+    }
+
+    public String getClusterId() {
+        return clusterId;
+    }
+
+    public void setClusterId(String clusterId) {
+        this.clusterId = clusterId;
+    }
+
+    public String getRegion() {
+        return region;
+    }
+
+    public void setRegion(String region) {
+        this.region = region;
+    }
+
+    public String getClientId() {
+        return clientId;
+    }
+
+    public void setClientId(String clientId) {
+        this.clientId = clientId;
+    }
+
+    public String getClientSecret() {
+        return clientSecret;
+    }
+
+    public void setClientSecret(String clientSecret) {
+        this.clientSecret = clientSecret;
+    }
+
+    public String getGrpcAddress() {
+        return grpcAddress;
+    }
+
+    public void setGrpcAddress(String grpcAddress) {
+        this.grpcAddress = grpcAddress;
+    }
+
+    public String getRestAddress() {
+        return restAddress;
+    }
+
+    public void setRestAddress(String restAddress) {
+        this.restAddress = restAddress;
+    }
+
+    public String getOAuthAPI() {
+        return oAuthAPI;
+    }
+
+    public void setOAuthAPI(String oAuthAPI) {
+        this.oAuthAPI = oAuthAPI;
+    }
+
+    @Override
+    protected void doStart() throws Exception {
+        super.doStart();
+
+        if (camundaService == null) {
+            CamundaClient client = buildClient();
+            camundaService = new CamundaService(client);
+        }
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        super.doStop();
+
+        if (camundaService != null) {
+            camundaService.doStop();
+            camundaService = null;
+        }
+    }
+
+    private CamundaClient buildClient() {
+        if (clusterId != null) {
+            return CamundaClient.newCloudClientBuilder()
+                    .withClusterId(clusterId)
+                    .withClientId(clientId)
+                    .withClientSecret(clientSecret)
+                    .withRegion(region)
+                    .build();
+        }
+
+        CamundaClientBuilder builder = CamundaClient.newClientBuilder()
+                .grpcAddress(URI.create(grpcAddress))
+                .restAddress(URI.create(restAddress));
+
+        if (clientId != null && oAuthAPI != null) {
+            builder.credentialsProvider(
+                    new io.camunda.client.impl.oauth.OAuthCredentialsProviderBuilder()
+                            .authorizationServerUrl(oAuthAPI)
+                            .audience(grpcAddress)
+                            .clientId(clientId)
+                            .clientSecret(clientSecret)
+                            .build());
+        }
+
+        return builder.build();

Review Comment:
   **Major**: When `clusterId` is null and no OAuth is configured (typical local Docker/dev setup), there's no way to disable TLS. The Camunda Java Client defaults to TLS, so connecting to a local non-TLS instance will fail.
   
   The zeebe component handles this with `usePlaintext()`. Consider adding a `usePlaintext` boolean component option for self-managed setups without TLS.



##########
components/camel-camunda/pom.xml:
##########
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.camel</groupId>
+        <artifactId>components</artifactId>
+        <version>4.19.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>camel-camunda</artifactId>
+    <packaging>jar</packaging>
+    <name>Camel :: Camunda</name>
+    <description>Camel Camunda component using the Camunda 8 Java Client</description>
+
+    <properties>
+        <firstVersion>4.19</firstVersion>
+        <supportLevel>Preview</supportLevel>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-support</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>io.camunda</groupId>
+            <artifactId>camunda-client-java</artifactId>
+            <version>${camunda-client-java-version}</version>

Review Comment:
   **Blocking**: The property `${camunda-client-java-version}` is not defined in `parent/pom.xml`. The build will fail. You need to add this property to the parent POM's `<properties>` section alongside the existing `zeebe-version` property.



##########
components/camel-camunda/src/main/java/org/apache/camel/component/camunda/internal/CamundaService.java:
##########
@@ -0,0 +1,267 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.camunda.internal;
+
+import java.time.Duration;
+import java.util.List;
+
+import io.camunda.client.CamundaClient;
+import io.camunda.client.api.command.CreateProcessInstanceCommandStep1;
+import io.camunda.client.api.response.DeploymentEvent;
+import io.camunda.client.api.response.Process;
+import io.camunda.client.api.response.ProcessInstanceEvent;
+import io.camunda.client.api.response.PublishMessageResponse;
+import io.camunda.client.api.worker.JobHandler;
+import io.camunda.client.api.worker.JobWorker;
+import org.apache.camel.component.camunda.model.DeploymentRequest;
+import org.apache.camel.component.camunda.model.DeploymentResponse;
+import org.apache.camel.component.camunda.model.JobRequest;
+import org.apache.camel.component.camunda.model.JobResponse;
+import org.apache.camel.component.camunda.model.MessageRequest;
+import org.apache.camel.component.camunda.model.MessageResponse;
+import org.apache.camel.component.camunda.model.ProcessDeploymentResponse;
+import org.apache.camel.component.camunda.model.ProcessRequest;
+import org.apache.camel.component.camunda.model.ProcessResponse;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CamundaService {
+    private static final Logger LOG = LoggerFactory.getLogger(CamundaService.class);
+
+    private final CamundaClient client;
+
+    public CamundaService(CamundaClient client) {
+        this.client = client;
+    }
+
+    public void doStop() {
+        if (client != null) {
+            client.close();
+        }
+    }
+
+    public ProcessResponse startProcess(ProcessRequest processMessage) {
+        ProcessResponse resultMessage = new ProcessResponse();
+        resultMessage.setProcessId(processMessage.getProcessId());
+
+        try {
+            CreateProcessInstanceCommandStep1.CreateProcessInstanceCommandStep3 step3;
+
+            CreateProcessInstanceCommandStep1.CreateProcessInstanceCommandStep2 step2
+                    = client.newCreateInstanceCommand()
+                            .bpmnProcessId(processMessage.getProcessId());
+
+            if (processMessage.getProcessVersion() > 0) {
+                step3 = step2.version(processMessage.getProcessVersion());
+            } else {
+                step3 = step2.latestVersion();
+            }
+
+            if (!processMessage.getVariables().isEmpty()) {

Review Comment:
   **Blocking**: If `getVariables()` returns `null` (e.g., from JSON deserialization, or explicit `setVariables(null)`), this throws NPE. The `Collections.emptyMap()` default only works if nobody calls `setVariables(null)`.
   
   Same issue on lines 136 and 157.
   
   ```suggestion
               if (processMessage.getVariables() != null && !processMessage.getVariables().isEmpty()) {
   ```



##########
components/camel-camunda/src/main/java/org/apache/camel/component/camunda/CamundaConsumer.java:
##########
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.camunda;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import io.camunda.client.api.response.ActivatedJob;
+import io.camunda.client.api.worker.JobClient;
+import io.camunda.client.api.worker.JobHandler;
+import io.camunda.client.api.worker.JobWorker;
+import org.apache.camel.AsyncCallback;
+import org.apache.camel.CamelException;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.component.camunda.internal.OperationName;
+import org.apache.camel.component.camunda.model.JobWorkerMessage;
+import org.apache.camel.support.DefaultConsumer;
+import org.apache.camel.util.ObjectHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CamundaConsumer extends DefaultConsumer {
+    private static final Logger LOG = LoggerFactory.getLogger(CamundaConsumer.class);
+
+    private final CamundaEndpoint endpoint;
+
+    private JobWorker jobWorker;
+
+    private ObjectMapper objectMapper = new ObjectMapper();
+
+    public CamundaConsumer(CamundaEndpoint endpoint, Processor processor) throws CamelException {
+        super(endpoint, processor);
+        this.endpoint = endpoint;
+    }
+
+    @Override
+    protected void doStart() throws Exception {
+        super.doStart();
+
+        final OperationName operationName = getEndpoint().getOperationName();
+        switch (operationName) {
+            case REGISTER_JOB_WORKER:
+                ObjectHelper.notNull(getEndpoint().getJobType(), "jobType");
+
+                jobWorker = getEndpoint().getCamundaService().registerJobHandler(new ConsumerJobHandler(),
+                        getEndpoint().getJobType(), getEndpoint().getTimeout());
+                break;
+            default:
+                throw new CamelException(String.format("Invalid Operation for Consumer %s", operationName.value()));
+        }
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        super.doStop();
+
+        if (jobWorker != null && jobWorker.isOpen()) {
+            jobWorker.close();
+        }
+    }
+
+    private class ConsumerJobHandler implements JobHandler {
+        @Override
+        public void handle(JobClient client, ActivatedJob job) throws Exception {

Review Comment:
   **Blocking**: The `JobClient client` parameter is received but never used. After the exchange is processed (line 114), the job is never completed or failed on the Camunda side. This means:
   - On success: the job will time out and be retried → duplicate processing
   - On failure: same behavior, no error feedback to Camunda
   
   Either:
   1. Auto-complete on success / auto-fail on exception (standard job worker pattern), or
   2. Document very prominently that the user's route **must** explicitly call `completeJob` or `failJob`
   
   The zeebe component has the same design, but it's still a footgun worth addressing in a new component.



##########
components/camel-camunda/src/main/java/org/apache/camel/component/camunda/CamundaEndpoint.java:
##########
@@ -0,0 +1,149 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.camunda;
+
+import java.util.Map;
+
+import org.apache.camel.Category;
+import org.apache.camel.Consumer;
+import org.apache.camel.Processor;
+import org.apache.camel.Producer;
+import org.apache.camel.component.camunda.internal.CamundaService;
+import org.apache.camel.component.camunda.internal.OperationName;
+import org.apache.camel.spi.EndpointServiceLocation;
+import org.apache.camel.spi.Metadata;
+import org.apache.camel.spi.UriEndpoint;
+import org.apache.camel.spi.UriParam;
+import org.apache.camel.spi.UriPath;
+import org.apache.camel.support.DefaultEndpoint;
+import org.apache.camel.util.ObjectHelper;
+
+/**
+ * Interact with Camunda 8 Orchestration Clusters using the Camunda Java Client.
+ */
+@UriEndpoint(firstVersion = "4.19.0", scheme = "camunda", title = "Camunda",
+             syntax = "camunda:operationName",
+             category = { Category.WORKFLOW, Category.SAAS },
+             headersClass = CamundaConstants.class)
+public class CamundaEndpoint extends DefaultEndpoint implements EndpointServiceLocation {
+
+    @UriPath(label = "common", description = "The operation to use",
+             enums = "startProcess,cancelProcess,publishMessage,completeJob,failJob,updateJobRetries,worker,throwError,deployResource")
+    @Metadata(required = true)
+    private OperationName operationName;
+
+    @UriParam(defaultValue = "false")
+    @Metadata(description = "Format the result in the body as JSON.")
+    private boolean formatJSON;
+
+    @UriParam
+    @Metadata(label = "consumer", description = "Job type for the job worker.")
+    private String jobType;
+
+    @UriParam(defaultValue = "10")
+    @Metadata(label = "consumer", description = "Timeout for job worker in seconds.")
+    private int timeout = 10;
+
+    public CamundaEndpoint() {
+    }
+
+    public CamundaEndpoint(String uri, CamundaComponent component, OperationName operationName) {
+        super(uri, component);
+        this.operationName = operationName;
+    }
+
+    @Override
+    public String getServiceUrl() {
+        if (getComponent().getClusterId() != null) {
+            return getComponent().getClusterId() + "." + getComponent().getRegion();
+        }
+        return getComponent().getGrpcAddress();
+    }
+
+    @Override
+    public String getServiceProtocol() {
+        return "rest";
+    }
+
+    @Override
+    public Map<String, String> getServiceMetadata() {
+        if (getComponent().getClientId() != null) {
+            return Map.of("clientId", getComponent().getClientId());
+        }
+        return null;
+    }
+
+    public Producer createProducer() throws Exception {

Review Comment:
   **Major**: No validation that the operation is appropriate for a producer. If someone creates `camunda://worker` as a producer, the `CamundaProducer` constructor won't find a matching processor and `processor` stays null, leading to `CamelException("No processor set")` at start.
   
   Validate here that `operationName != OperationName.REGISTER_JOB_WORKER` and throw a descriptive error. Same in `createConsumer()` (line 95) — validate that the operation is `REGISTER_JOB_WORKER` for consumers.



##########
components/camel-camunda/src/main/java/org/apache/camel/component/camunda/CamundaConstants.java:
##########
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.camunda;
+
+import org.apache.camel.spi.Metadata;
+
+public final class CamundaConstants {
+
+    public static final String HEADER_PREFIX = "CamelCamunda";
+
+    @Metadata(label = "producer", description = "Job key for the worker job", javaType = "long")

Review Comment:
   **Minor**: This header is also set by the consumer in `CamundaConsumer.ConsumerJobHandler.handle()` (line 100). Label should reflect that:
   
   ```suggestion
       @Metadata(label = "common", description = "Job key for the worker job", javaType = "long")
   ```



##########
components/camel-camunda/src/main/java/org/apache/camel/component/camunda/CamundaConsumer.java:
##########
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.camunda;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import io.camunda.client.api.response.ActivatedJob;
+import io.camunda.client.api.worker.JobClient;
+import io.camunda.client.api.worker.JobHandler;
+import io.camunda.client.api.worker.JobWorker;
+import org.apache.camel.AsyncCallback;
+import org.apache.camel.CamelException;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.component.camunda.internal.OperationName;
+import org.apache.camel.component.camunda.model.JobWorkerMessage;
+import org.apache.camel.support.DefaultConsumer;
+import org.apache.camel.util.ObjectHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CamundaConsumer extends DefaultConsumer {
+    private static final Logger LOG = LoggerFactory.getLogger(CamundaConsumer.class);
+
+    private final CamundaEndpoint endpoint;
+
+    private JobWorker jobWorker;
+
+    private ObjectMapper objectMapper = new ObjectMapper();
+
+    public CamundaConsumer(CamundaEndpoint endpoint, Processor processor) throws CamelException {

Review Comment:
   nit: Nothing in the constructor can throw `CamelException`. Remove it:
   
   ```suggestion
       public CamundaConsumer(CamundaEndpoint endpoint, Processor processor) {
   ```



##########
components/camel-camunda/src/main/java/org/apache/camel/component/camunda/processor/AbstractBaseProcessor.java:
##########
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.camunda.processor;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.camel.Exchange;
+import org.apache.camel.component.camunda.CamundaConstants;
+import org.apache.camel.component.camunda.CamundaEndpoint;
+import org.apache.camel.component.camunda.model.CamundaMessage;
+import org.apache.camel.support.service.BaseService;
+
+public abstract class AbstractBaseProcessor extends BaseService implements CamundaProcessor {
+    protected final CamundaEndpoint endpoint;
+    ObjectMapper objectMapper = new ObjectMapper();
+
+    public AbstractBaseProcessor(CamundaEndpoint endpoint) {
+        this.endpoint = endpoint;
+    }
+
+    protected void setBody(Exchange exchange, CamundaMessage message, boolean formatJSON) {

Review Comment:
   **Major**: The `formatJSON` parameter is accepted but never used — the method body uses `endpoint.isFormatJSON()` instead. Since all callers pass `endpoint.isFormatJSON()` anyway, remove the parameter to avoid confusion:
   
   ```suggestion
       protected void setBody(Exchange exchange, CamundaMessage message) {
   ```



##########
components/camel-camunda/src/main/java/org/apache/camel/component/camunda/internal/CamundaService.java:
##########
@@ -0,0 +1,267 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.camunda.internal;
+
+import java.time.Duration;
+import java.util.List;
+
+import io.camunda.client.CamundaClient;
+import io.camunda.client.api.command.CreateProcessInstanceCommandStep1;
+import io.camunda.client.api.response.DeploymentEvent;
+import io.camunda.client.api.response.Process;
+import io.camunda.client.api.response.ProcessInstanceEvent;
+import io.camunda.client.api.response.PublishMessageResponse;
+import io.camunda.client.api.worker.JobHandler;
+import io.camunda.client.api.worker.JobWorker;
+import org.apache.camel.component.camunda.model.DeploymentRequest;
+import org.apache.camel.component.camunda.model.DeploymentResponse;
+import org.apache.camel.component.camunda.model.JobRequest;
+import org.apache.camel.component.camunda.model.JobResponse;
+import org.apache.camel.component.camunda.model.MessageRequest;
+import org.apache.camel.component.camunda.model.MessageResponse;
+import org.apache.camel.component.camunda.model.ProcessDeploymentResponse;
+import org.apache.camel.component.camunda.model.ProcessRequest;
+import org.apache.camel.component.camunda.model.ProcessResponse;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CamundaService {
+    private static final Logger LOG = LoggerFactory.getLogger(CamundaService.class);
+
+    private final CamundaClient client;
+
+    public CamundaService(CamundaClient client) {
+        this.client = client;
+    }
+
+    public void doStop() {
+        if (client != null) {
+            client.close();
+        }
+    }
+
+    public ProcessResponse startProcess(ProcessRequest processMessage) {
+        ProcessResponse resultMessage = new ProcessResponse();
+        resultMessage.setProcessId(processMessage.getProcessId());
+
+        try {
+            CreateProcessInstanceCommandStep1.CreateProcessInstanceCommandStep3 step3;
+
+            CreateProcessInstanceCommandStep1.CreateProcessInstanceCommandStep2 step2
+                    = client.newCreateInstanceCommand()
+                            .bpmnProcessId(processMessage.getProcessId());
+
+            if (processMessage.getProcessVersion() > 0) {
+                step3 = step2.version(processMessage.getProcessVersion());
+            } else {
+                step3 = step2.latestVersion();
+            }
+
+            if (!processMessage.getVariables().isEmpty()) {
+                step3.variables(processMessage.getVariables());
+            }
+
+            ProcessInstanceEvent event = step3.send().join();
+
+            resultMessage.setProcessId(event.getBpmnProcessId());
+            resultMessage.setProcessKey(event.getProcessDefinitionKey());
+            resultMessage.setProcessVersion(event.getVersion());
+            resultMessage.setProcessInstanceKey(event.getProcessInstanceKey());
+            resultMessage.setSuccess(true);
+        } catch (Exception exception) {
+            LOG.error("Camunda Error", exception);
+            resultMessage.setProcessVersion(processMessage.getProcessVersion());
+            resultMessage.setErrorMessage(exception.getMessage());
+            resultMessage.setSuccess(false);
+        }
+
+        return resultMessage;
+    }
+
+    public ProcessResponse cancelProcessInstance(ProcessRequest processMessage) {
+        ProcessResponse resultMessage = new ProcessResponse();
+        resultMessage.setProcessInstanceKey(processMessage.getProcessInstanceKey());
+
+        try {
+            client.newCancelInstanceCommand(processMessage.getProcessInstanceKey())
+                    .send()
+                    .join();
+
+            resultMessage.setSuccess(true);
+        } catch (Exception exception) {
+            LOG.error("Cannot cancel process instance {}", processMessage.getProcessId(), exception);

Review Comment:
   **Minor**: For cancel operations, `processMessage.getProcessId()` may be null. The relevant identifier is the `processInstanceKey`.
   
   ```suggestion
               LOG.error("Cannot cancel process instance {}", processMessage.getProcessInstanceKey(), exception);
   ```



##########
components/camel-camunda/src/main/java/org/apache/camel/component/camunda/internal/CamundaService.java:
##########
@@ -0,0 +1,267 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.camunda.internal;
+
+import java.time.Duration;
+import java.util.List;
+
+import io.camunda.client.CamundaClient;
+import io.camunda.client.api.command.CreateProcessInstanceCommandStep1;
+import io.camunda.client.api.response.DeploymentEvent;
+import io.camunda.client.api.response.Process;
+import io.camunda.client.api.response.ProcessInstanceEvent;
+import io.camunda.client.api.response.PublishMessageResponse;
+import io.camunda.client.api.worker.JobHandler;
+import io.camunda.client.api.worker.JobWorker;
+import org.apache.camel.component.camunda.model.DeploymentRequest;
+import org.apache.camel.component.camunda.model.DeploymentResponse;
+import org.apache.camel.component.camunda.model.JobRequest;
+import org.apache.camel.component.camunda.model.JobResponse;
+import org.apache.camel.component.camunda.model.MessageRequest;
+import org.apache.camel.component.camunda.model.MessageResponse;
+import org.apache.camel.component.camunda.model.ProcessDeploymentResponse;
+import org.apache.camel.component.camunda.model.ProcessRequest;
+import org.apache.camel.component.camunda.model.ProcessResponse;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CamundaService {
+    private static final Logger LOG = LoggerFactory.getLogger(CamundaService.class);
+
+    private final CamundaClient client;
+
+    public CamundaService(CamundaClient client) {
+        this.client = client;
+    }
+
+    public void doStop() {
+        if (client != null) {
+            client.close();
+        }
+    }
+
+    public ProcessResponse startProcess(ProcessRequest processMessage) {
+        ProcessResponse resultMessage = new ProcessResponse();
+        resultMessage.setProcessId(processMessage.getProcessId());
+
+        try {
+            CreateProcessInstanceCommandStep1.CreateProcessInstanceCommandStep3 step3;
+
+            CreateProcessInstanceCommandStep1.CreateProcessInstanceCommandStep2 step2
+                    = client.newCreateInstanceCommand()
+                            .bpmnProcessId(processMessage.getProcessId());
+
+            if (processMessage.getProcessVersion() > 0) {
+                step3 = step2.version(processMessage.getProcessVersion());
+            } else {
+                step3 = step2.latestVersion();
+            }
+
+            if (!processMessage.getVariables().isEmpty()) {
+                step3.variables(processMessage.getVariables());
+            }
+
+            ProcessInstanceEvent event = step3.send().join();
+
+            resultMessage.setProcessId(event.getBpmnProcessId());
+            resultMessage.setProcessKey(event.getProcessDefinitionKey());
+            resultMessage.setProcessVersion(event.getVersion());
+            resultMessage.setProcessInstanceKey(event.getProcessInstanceKey());
+            resultMessage.setSuccess(true);
+        } catch (Exception exception) {
+            LOG.error("Camunda Error", exception);
+            resultMessage.setProcessVersion(processMessage.getProcessVersion());
+            resultMessage.setErrorMessage(exception.getMessage());
+            resultMessage.setSuccess(false);
+        }
+
+        return resultMessage;
+    }
+
+    public ProcessResponse cancelProcessInstance(ProcessRequest processMessage) {
+        ProcessResponse resultMessage = new ProcessResponse();
+        resultMessage.setProcessInstanceKey(processMessage.getProcessInstanceKey());
+
+        try {
+            client.newCancelInstanceCommand(processMessage.getProcessInstanceKey())
+                    .send()
+                    .join();
+
+            resultMessage.setSuccess(true);
+        } catch (Exception exception) {
+            LOG.error("Cannot cancel process instance {}", processMessage.getProcessId(), exception);
+            resultMessage.setErrorMessage(exception.getMessage());
+            resultMessage.setSuccess(false);
+        }
+
+        return resultMessage;
+    }
+
+    public MessageResponse publishMessage(MessageRequest message) {
+        MessageResponse resultMessage = new MessageResponse();
+        resultMessage.setCorrelationKey(message.getCorrelationKey());
+
+        try {
+            if (message.getCorrelationKey() == null) {
+                LOG.error("Correlation Key is missing!");
+                resultMessage.setSuccess(false);
+                resultMessage.setErrorMessage("Correlation Key is missing!");
+                return resultMessage;
+            }
+
+            var cmd = client.newPublishMessageCommand()
+                    .messageName(message.getName())
+                    .correlationKey(message.getCorrelationKey());
+
+            if (message.getTimeToLive() >= 0) {
+                cmd.timeToLive(Duration.ofMillis(message.getTimeToLive()));
+            }
+            if (message.getMessageId() != null) {
+                cmd.messageId(message.getMessageId());
+            }
+            if (!message.getVariables().isEmpty()) {
+                cmd.variables(message.getVariables());
+            }
+
+            PublishMessageResponse response = cmd.send().join();
+            resultMessage.setMessageKey(response.getMessageKey());
+            resultMessage.setSuccess(true);
+        } catch (Exception exception) {
+            LOG.error("Cannot publish message {}", message.getCorrelationKey(), exception);
+            resultMessage.setErrorMessage(exception.getMessage());
+            resultMessage.setSuccess(false);
+        }
+
+        return resultMessage;
+    }
+
+    public JobResponse completeJob(JobRequest message) {
+        JobResponse resultMessage = new JobResponse();
+
+        try {
+            var cmd = client.newCompleteCommand(message.getJobKey());
+            if (!message.getVariables().isEmpty()) {
+                cmd.variables(message.getVariables());
+            }
+            cmd.send().join();
+
+            resultMessage.setSuccess(true);
+        } catch (Exception exception) {
+            LOG.error("Cannot complete Job {}", message.getJobKey(), exception);
+            resultMessage.setErrorMessage(exception.getMessage());
+            resultMessage.setSuccess(false);
+        }
+
+        return resultMessage;
+    }
+
+    public JobResponse failJob(JobRequest message) {
+        JobResponse resultMessage = new JobResponse();
+
+        try {
+            var cmd = client.newFailCommand(message.getJobKey())
+                    .retries(message.getRetries());
+            if (message.getFailMessage() != null) {
+                cmd.errorMessage(message.getFailMessage());
+            }
+            cmd.send().join();
+
+            resultMessage.setSuccess(true);
+        } catch (Exception exception) {
+            LOG.error("Cannot fail Job {}", message.getJobKey(), exception);
+            resultMessage.setErrorMessage(exception.getMessage());
+            resultMessage.setSuccess(false);
+        }
+
+        return resultMessage;
+    }
+
+    public JobResponse updateJobRetries(JobRequest message) {
+        JobResponse resultMessage = new JobResponse();
+
+        try {
+            client.newUpdateRetriesCommand(message.getJobKey())
+                    .retries(message.getRetries())
+                    .send()
+                    .join();
+
+            resultMessage.setSuccess(true);
+        } catch (Exception exception) {
+            LOG.error("Cannot update retries for Job {}", message.getJobKey(), exception);
+            resultMessage.setErrorMessage(exception.getMessage());
+            resultMessage.setSuccess(false);
+        }
+
+        return resultMessage;
+    }
+
+    public JobResponse throwError(JobRequest message) {
+        JobResponse resultMessage = new JobResponse();
+
+        try {
+            var cmd = client.newThrowErrorCommand(message.getJobKey())
+                    .errorCode(message.getErrorCode());
+            if (message.getErrorMessage() != null) {
+                cmd.errorMessage(message.getErrorMessage());
+            }
+            cmd.send().join();
+
+            resultMessage.setSuccess(true);
+        } catch (Exception exception) {
+            LOG.error("Cannot throw error for Job {}", message.getJobKey(), exception);
+            resultMessage.setErrorMessage(exception.getMessage());
+            resultMessage.setSuccess(false);
+        }
+
+        return resultMessage;
+    }
+
+    public DeploymentResponse deployResource(DeploymentRequest message) {
+        DeploymentResponse resultMessage = new DeploymentResponse();
+
+        try {
+            DeploymentEvent event = client.newDeployResourceCommand()
+                    .addResourceBytes(message.getFileContent(), message.getName())
+                    .send()
+                    .join();
+
+            List<Process> processes = event.getProcesses();
+            if (!processes.isEmpty()) {
+                Process process = processes.get(0);

Review Comment:
   **Minor**: If a BPMN file contains multiple processes, only the first is reported. Consider logging a warning when `processes.size() > 1` so users know additional processes were deployed but not reported.



##########
components/camel-camunda/src/main/java/org/apache/camel/component/camunda/CamundaConsumer.java:
##########
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.camunda;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import io.camunda.client.api.response.ActivatedJob;
+import io.camunda.client.api.worker.JobClient;
+import io.camunda.client.api.worker.JobHandler;
+import io.camunda.client.api.worker.JobWorker;
+import org.apache.camel.AsyncCallback;
+import org.apache.camel.CamelException;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.component.camunda.internal.OperationName;
+import org.apache.camel.component.camunda.model.JobWorkerMessage;
+import org.apache.camel.support.DefaultConsumer;
+import org.apache.camel.util.ObjectHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CamundaConsumer extends DefaultConsumer {
+    private static final Logger LOG = LoggerFactory.getLogger(CamundaConsumer.class);
+
+    private final CamundaEndpoint endpoint;
+
+    private JobWorker jobWorker;
+
+    private ObjectMapper objectMapper = new ObjectMapper();

Review Comment:
   **Minor**: `ObjectMapper` is thread-safe and expensive to create. Consider making it a static final field shared across all instances. Same issue in `AbstractBaseProcessor`.
   
   ```suggestion
       private static final ObjectMapper objectMapper = new ObjectMapper();
   ```



##########
components/camel-camunda/src/main/java/org/apache/camel/component/camunda/processor/DeploymentProcessor.java:
##########
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.camunda.processor;
+
+import java.io.InputStream;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import org.apache.camel.CamelException;
+import org.apache.camel.Exchange;
+import org.apache.camel.component.camunda.CamundaConstants;
+import org.apache.camel.component.camunda.CamundaEndpoint;
+import org.apache.camel.component.camunda.internal.CamundaService;
+import org.apache.camel.component.camunda.model.DeploymentRequest;
+import org.apache.camel.component.camunda.model.DeploymentResponse;
+import org.apache.camel.component.camunda.model.ProcessDeploymentResponse;
+
+public class DeploymentProcessor extends AbstractBaseProcessor {
+    public DeploymentProcessor(CamundaEndpoint endpoint) {
+        super(endpoint);
+    }
+
+    @Override
+    public void process(Exchange exchange) throws Exception {
+        DeploymentRequest message = null;
+
+        Object body = exchange.getMessage().getBody();
+        String headerResourceName = exchange.getMessage().getHeader(CamundaConstants.RESOURCE_NAME, String.class);
+        if (headerResourceName != null && (body instanceof String || body instanceof byte[] || body instanceof InputStream)) {
+            message = new DeploymentRequest();
+            message.setName(headerResourceName);
+            if (body instanceof String) {
+                message.setFileContent(((String) body).getBytes());
+            } else if (body instanceof byte[]) {
+                message.setFileContent((byte[]) body);
+            } else {
+                message.setFileContent(((InputStream) body).readAllBytes());

Review Comment:
   **Major**: The `InputStream` is read but never closed. If `readAllBytes()` fails partway through, the stream leaks. Should use try-with-resources or close in a finally block.
   
   ```suggestion
                   try (InputStream is = (InputStream) body) {
                       message.setFileContent(is.readAllBytes());
                   }
   ```



##########
components/camel-camunda/src/main/java/org/apache/camel/component/camunda/internal/OperationName.java:
##########
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.camunda.internal;
+
+public enum OperationName {
+    START_PROCESS("startProcess"),
+    CANCEL_PROCESS("cancelProcess"),
+    PUBLISH_MESSAGE("publishMessage"),
+    COMPLETE_JOB("completeJob"),
+    FAIL_JOB("failJob"),
+    UPDATE_JOB_RETRIES("updateJobRetries"),
+    REGISTER_JOB_WORKER("worker"),
+    THROW_ERROR("throwError"),
+    DEPLOY_RESOURCE("deployResource");
+
+    private final String value;
+
+    OperationName(String value) {
+        this.value = value;
+    }
+
+    public String value() {
+        return value;
+    }
+
+    public static OperationName fromValue(String value) {
+        for (OperationName operationName : OperationName.values()) {
+            if (operationName.value.equals(value)) {
+                return operationName;
+            }
+        }
+        throw new IllegalArgumentException(value);

Review Comment:
   nit:
   ```suggestion
           throw new IllegalArgumentException("Unknown operation name: " + value);
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@camel.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] CAMEL-23269: Add new component camel-camunda for Camunda 8 [camel]

Posted by "ibek (via GitHub)" <gi...@apache.org>.
ibek commented on code in PR #22338:
URL: https://github.com/apache/camel/pull/22338#discussion_r3014306006


##########
components/camel-camunda/pom.xml:
##########
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.camel</groupId>
+        <artifactId>components</artifactId>
+        <version>4.19.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>camel-camunda</artifactId>
+    <packaging>jar</packaging>
+    <name>Camel :: Camunda</name>
+    <description>Camel Camunda component using the Camunda 8 Java Client</description>
+
+    <properties>
+        <firstVersion>4.19</firstVersion>
+        <supportLevel>Preview</supportLevel>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-support</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>io.camunda</groupId>
+            <artifactId>camunda-client-java</artifactId>
+            <version>${camunda-client-java-version}</version>

Review Comment:
   camunda-client version is defined here in parent/pom.xml:
   https://github.com/apache/camel/pull/22338/changes#diff-b5a06276719e759fe07dfe6f75d781be5f83d2215179d82bdb195ad035348214R101



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@camel.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] CAMEL-23269: Add new component camel-camunda for Camunda 8 [camel]

Posted by "ibek (via GitHub)" <gi...@apache.org>.
ibek commented on code in PR #22338:
URL: https://github.com/apache/camel/pull/22338#discussion_r3009272667


##########
catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/jbang/camel-jbang-configuration-metadata.json:
##########


Review Comment:
   I can certainly revert the change but this was autogenerated when I run: mvn clean install -DskipTests



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@camel.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] CAMEL-23269: Add new component camel-camunda for Camunda 8 [camel]

Posted by "ibek (via GitHub)" <gi...@apache.org>.
ibek commented on PR #22338:
URL: https://github.com/apache/camel/pull/22338#issuecomment-4154433703

   I tested it manually with Camunda SaaS. AFAIK we didn't even have integration tests in camel-zeebe so did at least the mocks like there.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@camel.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] CAMEL-23269: Add new component camel-camunda for Camunda 8 [camel]

Posted by "gansheer (via GitHub)" <gi...@apache.org>.
gansheer commented on PR #22338:
URL: https://github.com/apache/camel/pull/22338#issuecomment-4163615140

   > the pr doc validation has failed with:
   > 
   > ```
   >  [15:06:46.903] ERROR (asciidoctor): target of xref not found: components::camunda-component.adoc
   >     file: /home/runner/work/camel/camel/camel/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_19.adoc
   >     source: /home/runner/work/camel/camel/camel (branch: HEAD <worktree> | start path: docs/user-manual)
   > [15:06:46.907] ERROR (asciidoctor): target of xref not found: components::camunda-component.adoc
   >     file: /home/runner/work/camel/camel/camel/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_19.adoc
   >     source: /home/runner/work/camel/camel/camel (branch: HEAD <worktree> | start path: docs/user-manual)
   > [15:07:05.548] WARN (asciidoctor): 
   >     file: /home/runner/work/camel/camel/camel/docs/components/modules/ROOT/pages/camunda-component.adoc
   >     source: /home/runner/work/camel/camel/camel (branch: HEAD <worktree> | start path: docs/components)
   >     msg: {
   >       "msg": "Target spring-boot:example$json/camunda.json not found",
   >       "useId": 7,
   >       "jsonpath": "jsonpathcount$"
   >     }
   > ```
   > 
   > @gansheer is it because it is a new component and the PR job does not handle that o there is a real problem?
   
   Antora makes it really challenging to have these links to a prerelease version. We had a case like that a while ago (see [CAMEL-22669](https://issues.apache.org/jira/browse/CAMEL-22669)). In the end we removed the link.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@camel.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] CAMEL-23269: Add new component camel-camunda for Camunda 8 [camel]

Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on PR #22338:
URL: https://github.com/apache/camel/pull/22338#issuecomment-4154135004

   :star2: Thank you for your contribution to the Apache Camel project! :star2:
     :robot: CI automation will test this PR automatically.
   
     :camel: Apache Camel Committers, please review the following items:
   
     * First-time contributors **require MANUAL approval** for the GitHub Actions to run
     * You can use the command `/component-test (camel-)component-name1 (camel-)component-name2..` to request a test from the test bot although they are normally detected and executed by CI.
     * You can label PRs using `build-all`, `build-dependents`, `skip-tests` and `test-dependents` to fine-tune the checks executed by this PR.
     * Build and test logs are available in the summary page. **Only** [Apache Camel committers](https://camel.apache.org/community/team/#committers) have access to the summary.
     
     :warning: Be careful when sharing logs. Review their contents before sharing them publicly.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@camel.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] CAMEL-23269: Add new component camel-camunda for Camunda 8 [camel]

Posted by "apupier (via GitHub)" <gi...@apache.org>.
apupier commented on code in PR #22338:
URL: https://github.com/apache/camel/pull/22338#discussion_r3010194006


##########
catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/jbang/camel-jbang-configuration-metadata.json:
##########


Review Comment:
   I think you have old versions of Camel Jbang locally.
   
   I tried and it reverts the change for me.
   
   if we look at the history https://github.com/apache/camel/commits/main/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/jbang/camel-jbang-configuration-metadata.json , we can notice that gradle was removed for instance https://github.com/apache/camel/commit/d316bc07eeb5d0680103985474a780caedf690ba



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@camel.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] CAMEL-23269: Add new component camel-camunda for Camunda 8 [camel]

Posted by "apupier (via GitHub)" <gi...@apache.org>.
apupier merged PR #22338:
URL: https://github.com/apache/camel/pull/22338


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@camel.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org