Camunda: Difference between revisions

From Chorke Wiki
Jump to navigation Jump to search
No edit summary
 
(42 intermediate revisions by the same user not shown)
Line 1: Line 1:
<source lang="bash">
<syntaxhighlight lang="bash">
sudo mkdir -p /opt/ide
sudo mkdir -p /opt/ide
sudo wget -cq https://downloads.camunda.cloud/release/camunda-modeler/5.7.0/camunda-modeler-5.7.0-linux-x64.tar.gz -P /opt/ide
sudo wget -cq https://downloads.camunda.cloud/release/camunda-modeler/5.7.0/camunda-modeler-5.7.0-linux-x64.tar.gz -P /opt/ide
Line 7: Line 7:
sudo wget -cq https://camunda.com/wp-content/uploads/2022/02/Secondary-Logo_Rounded-Black-300x300.png\
sudo wget -cq https://camunda.com/wp-content/uploads/2022/02/Secondary-Logo_Rounded-Black-300x300.png\
  -O /opt/ide/camunda-modeler-5.7.0-linux-x64/camunda-modeler.png
  -O /opt/ide/camunda-modeler-5.7.0-linux-x64/camunda-modeler.png
</source>
</syntaxhighlight>


<source lang="ini">
<syntaxhighlight lang="ini">
cat << EOF | sudo tee /usr/share/applications/CamundaModeler.desktop >>/dev/null
cat << EOF | sudo tee /usr/share/applications/CamundaModeler.desktop >>/dev/null
[Desktop Entry]
[Desktop Entry]
Line 22: Line 22:
Categories=Development;IDE;BPMN;
Categories=Development;IDE;BPMN;
EOF
EOF
</source>
</syntaxhighlight>


==docker-compose.yml==
==docker-compose.yml==
<source lang="properties">
<syntaxhighlight lang="properties">
version: '3.4'
version: '3.4'


Line 38: Line 38:
       - ./h2:/app/camunda-h2-default
       - ./h2:/app/camunda-h2-default
       - ./forms:/app/client/xc-tasklist/forms
       - ./forms:/app/client/xc-tasklist/forms
</source>
</syntaxhighlight>


  docker-compose logs -ft
  docker-compose logs -ft
Line 45: Line 45:


==camunda.dev.chorke.org==
==camunda.dev.chorke.org==
<source lang="apache" highlight="16-22">
<syntaxhighlight lang="apache" highlight="16-22">
vim /etc/hosts
vim /etc/hosts
#127.0.0.1      camuda.dev.chorke.org
#127.0.0.1      camuda.dev.chorke.org
Line 78: Line 78:
sudo systemctl restart apache2
sudo systemctl restart apache2
sudo systemctl daemon-reload
sudo systemctl daemon-reload
</source>
</syntaxhighlight>


  '''http://camunda.dev.chorke.org/engine-rest/process-definition?latestVersion=true'''
  '''http://camunda.dev.chorke.org/engine-rest/process-definition?latestVersion=true'''
Line 94: Line 94:
  http://camunda.dev.chorke.org/camunda/engine-rest/
  http://camunda.dev.chorke.org/camunda/engine-rest/
  http://camunda.dev.chorke.org/camunda/swaggerui/
  http://camunda.dev.chorke.org/camunda/swaggerui/
http://dev.chorke.org/services/data/swaggerui/
http://dev.chorke.org/camunda/app/
  http://camunda.dev.chorke.org/ui/
  http://camunda.dev.chorke.org/ui/
  http://camunda.dev.chorke.org/
  http://camunda.dev.chorke.org/


==Invoking Java==
==Invoking Java==
<source lang="xml">
<syntaxhighlight lang="xml">
<repositories>
<repositories>
     <repository>
     <repository>
Line 106: Line 108:
     </repository>
     </repository>
</repositories>
</repositories>
</source>
</syntaxhighlight>


==Camunda Tomcat==
==Camunda Tomcat==
<source lang="bash">
<syntaxhighlight lang="bash">
groupadd tomcat
groupadd tomcat
useradd -s /bin/false -g tomcat -d /opt/camunda/camunda-bpm-tomcat-7.16.0/server/apache-tomcat-9.0.52/ tomcat
useradd -s /bin/false -g tomcat -d /opt/camunda/camunda-bpm-tomcat-7.16.0/server/apache-tomcat-9.0.52/ tomcat
Line 117: Line 119:
chmod g+x /opt/camunda/camunda-bpm-tomcat-7.16.0/server/apache-tomcat-9.0.52/conf
chmod g+x /opt/camunda/camunda-bpm-tomcat-7.16.0/server/apache-tomcat-9.0.52/conf
vim /etc/systemd/system/camunda.service
vim /etc/systemd/system/camunda.service
</source>
</syntaxhighlight>


<source lang="ini" highlight="3,4,9-12,16,17" line>
<syntaxhighlight lang="ini" highlight="3,4,9-12,16,17" line>
[Unit]
[Unit]
Description=Apache Tomcat Web Application Container
Description=Apache Tomcat Web Application Container
Line 146: Line 148:
[Install]
[Install]
WantedBy=multi-user.target
WantedBy=multi-user.target
</source>
</syntaxhighlight>


  systemctl status camunda.service
  systemctl status camunda.service
Line 162: Line 164:
  https://github.com/eugenp/tutorials/blob/master/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-feign-client/pom.xml
  https://github.com/eugenp/tutorials/blob/master/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-feign-client/pom.xml


<source lang="xml">
<syntaxhighlight lang="xml">
<version.chorke.spring.cloud>2021.0.0</version.chorke.spring.cloud>
<version.chorke.spring.cloud>2021.0.0</version.chorke.spring.cloud>
<version.chorke.spring.boot>2.6.3</version.chorke.spring.boot>
<version.chorke.spring.boot>2.6.3</version.chorke.spring.boot>
Line 186: Line 188:
     <artifactId>spring-cloud-starter-openfeign</artifactId>
     <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependency>
</source>
</syntaxhighlight>


==Export BPMN==
==Export BPMN==
<source lang="java">
<syntaxhighlight lang="java">
package io.xpresscover.services.camunda
package org.chorke.academia.services.camunda


import org.springframework.scheduling.annotation.Scheduled
import org.springframework.scheduling.annotation.Scheduled
Line 223: Line 225:
     }
     }
}
}
</source>
</syntaxhighlight>
 
==Update Workflow==
<syntaxhighlight lang="sql">
WITH xpath_metadata AS (
    SELECT
        (
            SELECT
                array_agg(array[
                    cast(raw_xpath_namespace->>0 AS varchar),
                    cast(raw_xpath_namespace->>1 AS varchar)
                ])
            FROM jsonb_array_elements('[
                ["bpmn",    "http://www.omg.org/spec/BPMN/20100524/MODEL"],
                ["camunda", "http://camunda.org/schema/1.0/bpmn"]
            ]'::jsonb) AS raw_xpath_namespace
        ) AS "namespaces"
        , 'count(//camunda:inputParameter[@name="url"])' AS "count_url"
        , '//camunda:inputParameter[@name="url"]/text()' AS "fetch_url"
        , '%https://staging.academia.chorke.org/%' AS "like_url"
        , 'https://staging.academia.chorke.org/' AS "find_url"
        , 'http://chorke.local/' AS "fill_url"
),
stored_dataflow AS (
    SELECT
        id_ AS "id", name_ AS "name", create_time_ AS "created_on"
        , convert_from(bytes_, 'UTF8') AS "dataflow"
    FROM act_ge_bytearray
),
stored_workflow AS (
    SELECT
        sd.id, sd.name, sd.created_on, sd.dataflow AS "old_workflow"
        , replace(sd.dataflow, xm.find_url, xm.fill_url) AS "new_workflow"
        , xpath(xm.fetch_url, sd.dataflow::xml, xm.namespaces) AS "old_node_found"
        ,(xpath(xm.count_url, sd.dataflow::xml, xm.namespaces))[1]::text::int AS "old_node_count"
    FROM stored_dataflow sd
    INNER JOIN xpath_metadata xm ON true
    WHERE xml_is_well_formed_document(sd.dataflow)
    AND  (xpath(xm.count_url, sd.dataflow::xml, xm.namespaces))[1]::text::int > 0
    ORDER BY sd.name ASC, sd.created_on DESC
),
edited_workflow AS (
    SELECT
        sw.*
        , xpath(xm.fetch_url, sw.new_workflow::xml, xm.namespaces) AS "new_node_found"
        ,(xpath(xm.count_url, sw.new_workflow::xml, xm.namespaces))[1]::text::int AS "new_node_count"
    FROM stored_workflow sw
    INNER JOIN xpath_metadata xm ON true
    AND  (xpath(xm.fetch_url, sw.old_workflow::xml, xm.namespaces))::text LIKE xm.like_url
)
-- UPDATE act_ge_bytearray ab SET
--    bytes_ = convert_to(ew.new_workflow, 'UTF8')
-- FROM edited_workflow ew
-- WHERE ew.old_workflow <> ew.new_workflow
-- AND  ab.id_ = ew.id
-- SELECT ew.* FROM edited_workflow ew;
SELECT sw.* FROM stored_workflow sw;
</syntaxhighlight>
 
==Workflow Tables==
{|class="wikitable"
|-
!scope="col"| SN !!scope="col"| Table !!scope="col"| Keys
|rowspan="21"|
!scope="col"| SN !!scope="col"| Table !!scope="col"| Keys
|-
|  00 || <code>act_ge_bytearray</code> || <code>id_, deployment_id_</code> || 20 || <code>act_ru_meter_log</code> || <code>id_</code>
|-
|  01 || <code>act_ge_property</code> || <code>id_</code> || 21 || <code>act_ru_task</code> || <code>id_, execution_id_, proc_inst_id_, proc_def_id_, case_execution_id_, case_def_id_</code>
|-
|  02 || <code>act_ge_schema_log</code> || <code>id_</code> || 22 || <code>act_ru_variable</code> || <code>id_, execution_id_, proc_inst_id_, case_execution_id_, case_inst_id_, batch_id_, bytearray_id_</code>
|-
|  03 || <code>act_hi_actinst</code> || <code>id_</code> || 23 || <code></code> || <code></code>
|-
|  04 || <code>act_hi_dec_in</code> || <code>id_</code> || 24 || <code></code> || <code></code>
|-
|  05 || <code>act_hi_dec_out</code> || <code>id_</code> || 25 || <code></code> || <code></code>
|-
|  06 || <code>act_hi_decinst</code> || <code>id_</code> || 26 || <code></code> || <code></code>
|-
|  07 || <code>act_hi_detail</code> || <code>id_</code> || 27 || <code></code> || <code></code>
|-
|  08 || <code>act_hi_op_log</code> || <code>id_</code> || 28 || <code></code> || <code></code>
|-
|  09 || <code>act_hi_procinst</code> || <code>id_</code> || 29 || <code></code> || <code></code>
|-
| 10 || <code>act_hi_taskinst</code> || <code>id_</code> || 30 || <code></code> || <code></code>
|-
| 11 || <code>act_hi_varinst</code> || <code>id_</code> || 31 || <code></code> || <code></code>
|-
| 12 || <code>act_id_group</code> || <code>id_</code> || 32 || <code></code> || <code></code>
|-
| 13 || <code>act_id_user</code> || <code>id_</code> || 33 || <code></code> || <code></code>
|-
| 14 || <code>act_re_decision_def</code> || <code>id_, dec_req_id_</code> || 34 || <code></code> || <code></code>
|-
| 15 || <code>act_re_decision_req_def</code> || <code>id_</code> || 35 || <code></code> || <code></code>
|-
| 16 || <code>act_re_deployment</code> || <code>id_</code> || 36 || <code></code> || <code></code>
|-
| 17 || <code>act_re_procdef</code> || <code>id_</code> || 37 || <code></code> || <code></code>
|-
| 18 || <code>act_ru_authorization</code> || <code>id_</code> || 38 || <code></code> || <code></code>
|-
| 19 || <code>act_ru_execution</code> || <code>id_, proc_inst_id_, parent_id_, proc_def_id_, super_exec_</code> || 39 || <code></code> || <code></code>
|}
 
==Stored Workflow==
<syntaxhighlight lang="sql">
WITH stored_dataflow AS (
    SELECT
        id_ AS "id", rev_ AS "revision",
        generated_ AS "is_generated", tenant_id_ AS "tenant_id",
        type_ AS "type", create_time_ AS "created_on", root_proc_inst_id_ AS "root_proc_inst_id",
        removal_time_ AS "deleted_on", name_ AS "name", convert_from(bytes_, 'UTF8') AS "dataflow"
    FROM act_ge_bytearray
),
stored_workflow AS (
    SELECT
        id, name, type, revision, is_generated,
        created_on, deleted_on, root_proc_inst_id,
        CAST(dataflow AS xml) AS "workflow", dataflow
    FROM stored_dataflow
    WHERE starts_with(dataflow, '<?xml version="1.0" encoding="UTF-8"?>')
    AND xml_is_well_formed_document(dataflow)
    ORDER BY name ASC, created_on DESC
)
SELECT * FROM stored_workflow;
</syntaxhighlight>
----
<syntaxhighlight lang="sql">
WITH xpath_metadata AS (
    SELECT
        (
            SELECT
                array_agg(array[
                    cast(raw_xpath_namespace->>0 AS varchar),
                    cast(raw_xpath_namespace->>1 AS varchar)
                ])
            FROM jsonb_array_elements('[
                ["bpmn",    "http://www.omg.org/spec/BPMN/20100524/MODEL"],
                ["bpmndi",  "http://www.omg.org/spec/BPMN/20100524/DI"],
                ["dc",      "http://www.omg.org/spec/DD/20100524/DC"],
                ["di",      "http://www.omg.org/spec/DD/20100524/DI"],
                ["modeler", "http://camunda.org/schema/modeler/1.0"],
                ["camunda", "http://camunda.org/schema/1.0/bpmn"]
            ]'::jsonb) AS raw_xpath_namespace
        ) AS "namespaces",
        '/*/bpmn:process/*/*/*/*/camunda:inputParameter[@name="url" or @name="payload"]/text()' AS "fetch_url_and_payload_query",
        'count(/*/bpmn:process/*/*/*/*/camunda:inputParameter[@name="url" or @name="payload"])' AS "count_url_and_payload_query"
),
stored_dataflow AS (
    SELECT
        id_ AS "id", rev_ AS "revision",
        generated_ AS "is_generated", tenant_id_ AS "tenant_id",
        type_ AS "type", create_time_ AS "created_on", root_proc_inst_id_ AS "root_proc_inst_id",
        removal_time_ AS "deleted_on", name_ AS "name", convert_from(bytes_, 'UTF8') AS "dataflow"
    FROM act_ge_bytearray
),
stored_workflow AS (
    SELECT
        sd.*,
        CAST(sd.dataflow AS xml) AS "workflow"
    FROM stored_dataflow sd
    WHERE xml_is_well_formed_document(sd.dataflow)
    ORDER BY sd.name ASC, sd.created_on DESC
)
SELECT
    sw.*,
    xpath(xm.fetch_url_and_payload_query, sw.workflow, xm.namespaces) AS "fetch_url_and_payload",
    (xpath(xm.count_url_and_payload_query, sw.workflow, xm.namespaces))[1]::text::int AS "count_url_and_payload"
FROM stored_workflow sw
INNER JOIN xpath_metadata xm ON true
WHERE (xpath(xm.count_url_and_payload_query, sw.workflow, xm.namespaces))[1]::text::int > 0
</syntaxhighlight>
 
==Playground==
<syntaxhighlight lang="sql">
WITH xpath_metadata AS (
    SELECT
        (
            SELECT
                array_agg(array[
                    cast(raw_xpath_namespace->>0 AS varchar),
                    cast(raw_xpath_namespace->>1 AS varchar)
            ])
            FROM jsonb_array_elements('[
                ["bpmn",    "http://www.omg.org/spec/BPMN/20100524/MODEL"],
                ["bpmndi",  "http://www.omg.org/spec/BPMN/20100524/DI"],
                ["dc",      "http://www.omg.org/spec/DD/20100524/DC"],
                ["di",      "http://www.omg.org/spec/DD/20100524/DI"],
                ["modeler", "http://camunda.org/schema/modeler/1.0"],
                ["camunda", "http://camunda.org/schema/1.0/bpmn"]
            ]'::jsonb) AS raw_xpath_namespace
        ) AS "namespaces"
        , 'count(/*/bpmn:process/*/*/*/*/camunda:inputParameter[@name="url" or @name="payload"])' AS "count_url_payload"
        , '/*/bpmn:process/*/*/*/*/camunda:inputParameter[@name="url" or @name="payload"]/text()' AS "fetch_url_payload"
        , '{"username": "admin", "password": "p@$$W0rd"}' AS "find_payload"
        , '{"username": "admin", "password": "p@55W0rd"}' AS "fill_payload"
        , 'https://staging.academia.chorke.org' AS "find_base_url"
        , 'http://chorke.local' AS "fill_base_url"
),
stored_workflow AS (
    SELECT
        '<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_0wdjv5g" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.12.0" modeler:executionPlatform="Camunda Platform" modeler:executionPlatformVersion="7.15.0">
  <bpmn:process id="create-quotation" name="Create Quotation" isExecutable="true">
    <bpmn:startEvent id="StartEvent_1">
      <bpmn:outgoing>Flow_03agry8</bpmn:outgoing>
    </bpmn:startEvent>
    <bpmn:endEvent id="Event_04jx9c3">
      <bpmn:incoming>Flow_0g38t01</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:sequenceFlow id="Flow_0g38t01" sourceRef="Activity_1ia0put" targetRef="Event_04jx9c3" />
    <bpmn:serviceTask id="Activity_1ia0put" name="Create Quotation">
      <bpmn:extensionElements>
        <camunda:connector>
          <camunda:inputOutput>
            <camunda:inputParameter name="payload">{
    "properties":{
      "version": "2",
      "Source":"B2B Portal",
      "Plan Type":"${planType}",
      "Plan":"${plan}",
      "Price":{
        "Rate":"${result.rate}",
        "Total":"${result.total}",
        "Driver Fee":"${result.driverFee}"
      },
      "Full Name":"${fullName}",
      "Nationality":"${nationality}",
      "ID Number":"${idNumber}",
      "ID Type":"${idDocType}",
      "Postcode":"${postcode}",
      "Country":"${country}"
    },
    "productSlug": "${productSlug}",
    "productName": "${productName}",
    "productCode": "${productCode}",
    "totalPremium": ${result.total}
}</camunda:inputParameter>
            <camunda:inputParameter name="url">https://staging.academia.chorke.org/services/quote/quotations/v2/${productSlug}</camunda:inputParameter>
            <camunda:inputParameter name="method">POST</camunda:inputParameter>
            <camunda:inputParameter name="headers">
              <camunda:map>
                <camunda:entry key="Accept">application/json</camunda:entry>
                <camunda:entry key="Content-Type">application/json</camunda:entry>
                <camunda:entry key="X-Auth-Token">${token}</camunda:entry>
                <camunda:entry key="X-Auth-Internal-Key">A7E6EF345E24117DCF3B586981223</camunda:entry>
              </camunda:map>
            </camunda:inputParameter>
            <camunda:outputParameter name="refCode">${JSON(response).prop("refCode").value()}</camunda:outputParameter>
            <camunda:outputParameter name="refId">${JSON(response).prop("refId").value()}</camunda:outputParameter>
          </camunda:inputOutput>
          <camunda:connectorId>http-connector</camunda:connectorId>
        </camunda:connector>
      </bpmn:extensionElements>
      <bpmn:incoming>Flow_1s5n3n6</bpmn:incoming>
      <bpmn:outgoing>Flow_0g38t01</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:sequenceFlow id="Flow_1s5n3n6" sourceRef="Activity_1u1wyzg" targetRef="Activity_1ia0put" />
    <bpmn:serviceTask id="Activity_1u1wyzg" name="Get Token">
      <bpmn:extensionElements>
        <camunda:connector>
          <camunda:inputOutput>
            <camunda:inputParameter name="payload">{"username": "admin", "password": "p@$$W0rd"}</camunda:inputParameter>
            <camunda:inputParameter name="url">https://staging.academia.chorke.org/services/auth/identity/users/login</camunda:inputParameter>
            <camunda:inputParameter name="method">POST</camunda:inputParameter>
            <camunda:inputParameter name="headers">
              <camunda:map>
                <camunda:entry key="Accept">application/json</camunda:entry>
                <camunda:entry key="Content-Type">application/json</camunda:entry>
              </camunda:map>
            </camunda:inputParameter>
            <camunda:outputParameter name="token">${S(response).prop("token").value()}</camunda:outputParameter>
          </camunda:inputOutput>
          <camunda:connectorId>http-connector</camunda:connectorId>
        </camunda:connector>
      </bpmn:extensionElements>
      <bpmn:incoming>Flow_03agry8</bpmn:incoming>
      <bpmn:outgoing>Flow_1s5n3n6</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:sequenceFlow id="Flow_03agry8" sourceRef="StartEvent_1" targetRef="Activity_1u1wyzg" />
  </bpmn:process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="create-quotation">
      <bpmndi:BPMNEdge id="Flow_1s5n3n6_di" bpmnElement="Flow_1s5n3n6">
        <di:waypoint x="360" y="210" />
        <di:waypoint x="460" y="210" />
        <di:waypoint x="460" y="140" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_0g38t01_di" bpmnElement="Flow_0g38t01">
        <di:waypoint x="510" y="100" />
        <di:waypoint x="562" y="100" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_03agry8_di" bpmnElement="Flow_03agry8">
        <di:waypoint x="208" y="100" />
        <di:waypoint x="234" y="100" />
        <di:waypoint x="234" y="210" />
        <di:waypoint x="260" y="210" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
        <dc:Bounds x="172" y="82" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Event_04jx9c3_di" bpmnElement="Event_04jx9c3">
        <dc:Bounds x="562" y="82" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Activity_00l2f3y_di" bpmnElement="Activity_1ia0put">
        <dc:Bounds x="410" y="60" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Activity_1bsx6ed_di" bpmnElement="Activity_1u1wyzg">
        <dc:Bounds x="260" y="170" width="100" height="80" />
      </bpmndi:BPMNShape>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn:definitions>'::xml AS "workflow"
)
SELECT
    (  xpath(xm.count_url_payload, sw.workflow, xm.namespaces))[1]::text::int AS "count"
    ,  xpath_exists(xm.fetch_url_payload, sw.workflow, xm.namespaces) AS "exists"
    ,  xpath(xm.fetch_url_payload, sw.workflow, xm.namespaces) AS "fetch"
    ,  sw.workflow::text as "old_workflow"
    ,  replace(
            replace(sw.workflow::text, xm.find_base_url, xm.fill_base_url)
            , xm.find_payload
            , xm.fill_payload
        ) AS "new_workflow"
FROM stored_workflow sw
INNER JOIN xpath_metadata xm ON true
WHERE  (xpath(xm.count_url_payload, sw.workflow, xm.namespaces))[1]::text::int > 0
</syntaxhighlight>


==Knowledge==
==Knowledge==
Line 364: Line 696:


| valign="top" |
| valign="top" |
* [https://medium.com/kie-foundation/3-steps-to-online-vs-code-experience-for-business-automation-developers-f4835dd7f4b5 VS Code Experience for BPMN Developers]
* [https://marketplace.visualstudio.com/items?itemName=kie-group.vscode-extension-kogito-bundle Drools » VSCode » Kogito Bundle]
* [https://marketplace.visualstudio.com/items?itemName=kie-group.vscode-extension-kogito-bundle Drools » VSCode » Kogito Bundle]
* [https://docs.camunda.org/manual/latest/reference/rest/ Camunda » Docs » Rest » Latest]
* [https://docs.kogito.kie.org/latest/html_single/ Drools » Kogito Documentation]
* [https://docs.kogito.kie.org/latest/html_single/ Drools » Kogito Documentation]
* [https://docs.camunda.org/manual/7.17/reference/rest/ Camunda » Docs » Rest » 7.17]
* [https://docs.camunda.org/manual/7.7/reference/rest/ Camunda » Docs » Rest » 7.7]
* [https://porcelli.me/announcement/tooling/vscode/bpmn/2019/09/11/new-vscode-gui-editor.html BPMN Extension for VSCode]
* [https://stackoverflow.com/questions/tagged/camunda Camunda » Stack Overflow]
* [https://docs.jboss.org/drools/release/latestFinal/drools-docs/docs-website/drools/introduction/index.html Drools » Documentation]
* [https://docs.jboss.org/drools/release/latestFinal/drools-docs/docs-website/drools/introduction/index.html Drools » Documentation]
* [[Drools]]
|-
| colspan="3" |
----
|-
| valign="top" |
* [https://forum.camunda.io/t/what-is-the-relations-between-the-tables-where-we-are-storing-camunda-meta-data/30610 Camunda » Relations between the tables]
* [https://github.com/camunda/camunda-bpm-platform/tree/master/distro Camunda » SCM » Distribution]
* [https://github.com/camunda/camunda-bpm-platform/blob/master/database/ Camunda » SCM » Database]
* [https://docs.camunda.io/docs/self-managed/zeebe-deployment/zeebe-gateway/overview/ Camunda » Zeebe Gateway]
* [https://github.com/camunda/camunda-platform Camunda » SCM » Platform]
* [https://github.com/camunda Camunda » SCM]
* [[Dropwizard]]
| valign="top" |
| valign="top" |


|}
|}

Latest revision as of 10:00, 26 October 2024

sudo mkdir -p /opt/ide
sudo wget -cq https://downloads.camunda.cloud/release/camunda-modeler/5.7.0/camunda-modeler-5.7.0-linux-x64.tar.gz -P /opt/ide
sudo tar -xzf /opt/ide/camunda-modeler-5.7.0-linux-x64.tar.gz -C /opt/ide
sudo rm  -rf  /opt/ide/camunda-modeler-5.7.0-linux-x64.tar.gz

sudo wget -cq https://camunda.com/wp-content/uploads/2022/02/Secondary-Logo_Rounded-Black-300x300.png\
 -O /opt/ide/camunda-modeler-5.7.0-linux-x64/camunda-modeler.png
cat << EOF | sudo tee /usr/share/applications/CamundaModeler.desktop >>/dev/null
[Desktop Entry]
Name=Camunda Modeler 5
Comment=SpringSource Tool Suite 4
Exec=/opt/ide/camunda-modeler-5.7.0-linux-x64/camunda-modeler
Icon=/opt/ide/camunda-modeler-5.7.0-linux-x64/camunda-modeler.png
StartupNotify=true
Terminal=false
Type=Application
Keywords=Camunda,Modeler,BPMN,IDE,Development
Categories=Development;IDE;BPMN;
EOF

docker-compose.yml

version: '3.4'

services:
  academia-poc:
    image: camunda/camunda-bpm-platform:run-latest
    container_name: academia_poc
    restart: always
    ports:
      - 127.0.0.1:15010:8080
    volumes:
      - ./h2:/app/camunda-h2-default
      - ./forms:/app/client/xc-tasklist/forms
docker-compose logs -ft
docker-compose up -d
docker-compose down

camunda.dev.chorke.org

vim /etc/hosts
#127.0.0.1       camuda.dev.chorke.org

mkdir /var/log/apache2/camuda.dev.chorke.org

cat <<'EOF' > /etc/apache2/sites-enabled/00-camuda.dev.chorke.org.conf
<VirtualHost *:80>
    ProxyRequests Off
    ProxyPreserveHost On
    AllowEncodedSlashes Off

    ServerAdmin [email protected]
    ServerAlias camunda.dev.chorke.org
    ServerName www.camunda.dev.chorke.org

    <Location />
        Order Allow,Deny
        Allow from all
        RequestHeader set "Host" "camunda.dev.chorke.org"
        ProxyPass http://127.0.0.1:15010/ nocanon
        ProxyPassReverse http://127.0.0.1:15010/
    </Location>

    ErrorLog ${APACHE_LOG_DIR}/camunda.dev.chorke.org/error.log
    CustomLog ${APACHE_LOG_DIR}/camunda.dev.chorke.org/access.log combined
</VirtualHost>
EOF

a2enmod headers
sudo apachectl -t
sudo systemctl restart apache2
sudo systemctl daemon-reload
http://camunda.dev.chorke.org/engine-rest/process-definition?latestVersion=true
http://camunda.dev.chorke.org/engine-rest/task?processInstanceId={processID}&withoutTenantId=false&includeAssignedTasks=false&assigned=false&unassigned=false&withoutDueDate=false&withCandidateGroups=false&withoutCandidateGroups=false&withCandidateUsers=false&withoutCandidateUsers=false&active=false&suspended=false&variableNamesIgnoreCase=false&variableValuesIgnoreCase=false

http://camunda.dev.chorke.org/camunda/app/cockpit/default/#/dashboard
http://camunda.dev.chorke.org/camunda/app/welcome/default/#!/welcome
http://camunda.dev.chorke.org/camunda/app/tasklist/default/#/
http://camunda.dev.chorke.org/camunda/app/admin/default/#/
http://camunda.dev.chorke.org/

http://camunda.dev.chorke.org/camunda/swaggerui/#/Process%20Definition/getProcessDefinitions
http://camunda.dev.chorke.org/camunda/engine-rest/deployment/create
http://camunda.dev.chorke.org/camunda/app/tasklist/default/
http://camunda.dev.chorke.org/camunda/engine-rest/
http://camunda.dev.chorke.org/camunda/swaggerui/
http://dev.chorke.org/services/data/swaggerui/
http://dev.chorke.org/camunda/app/
http://camunda.dev.chorke.org/ui/
http://camunda.dev.chorke.org/

Invoking Java

<repositories>
    <repository>
        <id>camunda-bpm-artifactory</id>
        <name>camunda-bpm-artifactory</name>
        <url>https://camunda.jfrog.io/artifactory/public/</url>
    </repository>
</repositories>

Camunda Tomcat

groupadd tomcat
useradd -s /bin/false -g tomcat -d /opt/camunda/camunda-bpm-tomcat-7.16.0/server/apache-tomcat-9.0.52/ tomcat
chown -R tomcat /opt/camunda/camunda-bpm-tomcat-7.16.0/server/apache-tomcat-9.0.52/{webapps,work,temp,logs}
chgrp -R tomcat /opt/camunda/camunda-bpm-tomcat-7.16.0/server/apache-tomcat-9.0.52/
chmod -R g+r /opt/camunda/camunda-bpm-tomcat-7.16.0/server/apache-tomcat-9.0.52/conf
chmod g+x /opt/camunda/camunda-bpm-tomcat-7.16.0/server/apache-tomcat-9.0.52/conf
vim /etc/systemd/system/camunda.service
[Unit]
Description=Apache Tomcat Web Application Container
After=syslog.target network.target
Before=httpd.service

[Service]
Type=forking

Environment=JAVA_HOME=/usr/lib/jvm/java-8-openjdk-armhf/jre
Environment=CATALINA_PID=/opt/camunda/camunda-bpm-tomcat-7.16.0/server/apache-tomcat-9.0.52/temp/tomcat.pid
Environment=CATALINA_HOME=/opt/camunda/camunda-bpm-tomcat-7.16.0/server/apache-tomcat-9.0.52
Environment=CATALINA_BASE=/opt/camunda/camunda-bpm-tomcat-7.16.0/server/apache-tomcat-9.0.52
Environment='CATALINA_OPTS=-Xms512M -Xmx1024M -server -XX:+UseParallelGC'
Environment='JAVA_OPTS=-Djava.awt.headless=true -Djava.security.egd=file:/dev/./urandom'

ExecStart=/opt/camunda/camunda-bpm-tomcat-7.16.0/server/apache-tomcat-9.0.52/bin/startup.sh
ExecStop=/opt/camunda/camunda-bpm-tomcat-7.16.0/server/apache-tomcat-9.0.52/bin/shutdown.sh

User=tomcat
Group=tomcat
UMask=0007
RestartSec=10
Restart=always

[Install]
WantedBy=multi-user.target
systemctl status camunda.service
systemctl enable camunda.service
systemctl start  camunda.service

Netflix Eureka

Lookup for Version
https://www.baeldung.com/spring-cloud-netflix-eureka
https://github.com/eugenp/tutorials/tree/master/spring-cloud/spring-cloud-eureka

Lookup for Dependency
https://github.com/eugenp/tutorials/blob/master/parent-boot-2/pom.xml
https://github.com/eugenp/tutorials/blob/master/spring-cloud/pom.xml
https://github.com/eugenp/tutorials/blob/master/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-feign-client/pom.xml
<version.chorke.spring.cloud>2021.0.0</version.chorke.spring.cloud>
<version.chorke.spring.boot>2.6.3</version.chorke.spring.boot>

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-dependencies</artifactId>
    <version>${version.chorke.spring.cloud}</version>
    <scope>import</scope>
    <type>pom</type>
</dependency>

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

Export BPMN

package org.chorke.academia.services.camunda

import org.springframework.scheduling.annotation.Scheduled
import org.springframework.stereotype.Service
import org.camunda.bpm.engine.RuntimeService
import org.camunda.bpm.engine.ProcessEngine
import org.slf4j.LoggerFactory
import java.io.BufferedReader

@Service
class ExportProcessModel(
    var runtimeService: RuntimeService,
    var processEngine: ProcessEngine
) {
    val log = LoggerFactory.getLogger(ExportProcessModel::class.java)

    @Scheduled(fixedDelay = 15000, initialDelay = 15000)
    fun export() {
        val mutableList = processEngine.getRepositoryService().createProcessDefinitionQuery().list()
        for (processDefinition in mutableList) {
            val inputStream = processEngine.getRepositoryService().getProcessModel(processDefinition.id)
            val bufferedReader = BufferedReader(inputStream.reader())
            var xml: String

            try {
                xml = bufferedReader.readText()
                log.info("Model: \n{}", xml)
            } finally {
                bufferedReader.close()
            }
        }
    }
}

Update Workflow

WITH xpath_metadata AS (
    SELECT
        (
            SELECT
                array_agg(array[
                    cast(raw_xpath_namespace->>0 AS varchar),
                    cast(raw_xpath_namespace->>1 AS varchar)
                ])
            FROM jsonb_array_elements('[
                ["bpmn",    "http://www.omg.org/spec/BPMN/20100524/MODEL"],
                ["camunda", "http://camunda.org/schema/1.0/bpmn"]
            ]'::jsonb) AS raw_xpath_namespace
        ) AS "namespaces"
        , 'count(//camunda:inputParameter[@name="url"])' AS "count_url"
        , '//camunda:inputParameter[@name="url"]/text()' AS "fetch_url"
        , '%https://staging.academia.chorke.org/%' AS "like_url"
        , 'https://staging.academia.chorke.org/' AS "find_url"
        , 'http://chorke.local/' AS "fill_url"
),
stored_dataflow AS (
    SELECT
        id_ AS "id", name_ AS "name", create_time_ AS "created_on"
        , convert_from(bytes_, 'UTF8') AS "dataflow"
    FROM act_ge_bytearray
),
stored_workflow AS (
    SELECT
        sd.id, sd.name, sd.created_on, sd.dataflow AS "old_workflow"
        , replace(sd.dataflow, xm.find_url, xm.fill_url) AS "new_workflow"
        , xpath(xm.fetch_url, sd.dataflow::xml, xm.namespaces) AS "old_node_found"
        ,(xpath(xm.count_url, sd.dataflow::xml, xm.namespaces))[1]::text::int AS "old_node_count"
    FROM stored_dataflow sd
    INNER JOIN xpath_metadata xm ON true
    WHERE xml_is_well_formed_document(sd.dataflow)
    AND  (xpath(xm.count_url, sd.dataflow::xml, xm.namespaces))[1]::text::int > 0
    ORDER BY sd.name ASC, sd.created_on DESC
),
edited_workflow AS (
    SELECT
        sw.*
        , xpath(xm.fetch_url, sw.new_workflow::xml, xm.namespaces) AS "new_node_found"
        ,(xpath(xm.count_url, sw.new_workflow::xml, xm.namespaces))[1]::text::int AS "new_node_count"
    FROM stored_workflow sw
    INNER JOIN xpath_metadata xm ON true
    AND  (xpath(xm.fetch_url, sw.old_workflow::xml, xm.namespaces))::text LIKE xm.like_url
)
-- UPDATE act_ge_bytearray ab SET
--     bytes_ = convert_to(ew.new_workflow, 'UTF8')
-- FROM edited_workflow ew
-- WHERE ew.old_workflow <> ew.new_workflow
-- AND   ab.id_ = ew.id
-- SELECT ew.* FROM edited_workflow ew;
SELECT sw.* FROM stored_workflow sw;

Workflow Tables

SN Table Keys SN Table Keys
00 act_ge_bytearray id_, deployment_id_ 20 act_ru_meter_log id_
01 act_ge_property id_ 21 act_ru_task id_, execution_id_, proc_inst_id_, proc_def_id_, case_execution_id_, case_def_id_
02 act_ge_schema_log id_ 22 act_ru_variable id_, execution_id_, proc_inst_id_, case_execution_id_, case_inst_id_, batch_id_, bytearray_id_
03 act_hi_actinst id_ 23
04 act_hi_dec_in id_ 24
05 act_hi_dec_out id_ 25
06 act_hi_decinst id_ 26
07 act_hi_detail id_ 27
08 act_hi_op_log id_ 28
09 act_hi_procinst id_ 29
10 act_hi_taskinst id_ 30
11 act_hi_varinst id_ 31
12 act_id_group id_ 32
13 act_id_user id_ 33
14 act_re_decision_def id_, dec_req_id_ 34
15 act_re_decision_req_def id_ 35
16 act_re_deployment id_ 36
17 act_re_procdef id_ 37
18 act_ru_authorization id_ 38
19 act_ru_execution id_, proc_inst_id_, parent_id_, proc_def_id_, super_exec_ 39

Stored Workflow

WITH stored_dataflow AS (
    SELECT
        id_ AS "id", rev_ AS "revision",
        generated_ AS "is_generated", tenant_id_ AS "tenant_id",
        type_ AS "type", create_time_ AS "created_on", root_proc_inst_id_ AS "root_proc_inst_id",
        removal_time_ AS "deleted_on", name_ AS "name", convert_from(bytes_, 'UTF8') AS "dataflow"
    FROM act_ge_bytearray
),
stored_workflow AS (
    SELECT
        id, name, type, revision, is_generated,
        created_on, deleted_on, root_proc_inst_id,
        CAST(dataflow AS xml) AS "workflow", dataflow
    FROM stored_dataflow
    WHERE starts_with(dataflow, '<?xml version="1.0" encoding="UTF-8"?>')
    AND xml_is_well_formed_document(dataflow)
    ORDER BY name ASC, created_on DESC
)
SELECT * FROM stored_workflow;

WITH xpath_metadata AS (
    SELECT
        (
            SELECT
                array_agg(array[
                    cast(raw_xpath_namespace->>0 AS varchar),
                    cast(raw_xpath_namespace->>1 AS varchar)
                ])
            FROM jsonb_array_elements('[
                ["bpmn",    "http://www.omg.org/spec/BPMN/20100524/MODEL"],
                ["bpmndi",  "http://www.omg.org/spec/BPMN/20100524/DI"],
                ["dc",      "http://www.omg.org/spec/DD/20100524/DC"],
                ["di",      "http://www.omg.org/spec/DD/20100524/DI"],
                ["modeler", "http://camunda.org/schema/modeler/1.0"],
                ["camunda", "http://camunda.org/schema/1.0/bpmn"]
            ]'::jsonb) AS raw_xpath_namespace
        ) AS "namespaces",
        '/*/bpmn:process/*/*/*/*/camunda:inputParameter[@name="url" or @name="payload"]/text()' AS "fetch_url_and_payload_query",
        'count(/*/bpmn:process/*/*/*/*/camunda:inputParameter[@name="url" or @name="payload"])' AS "count_url_and_payload_query"
),
stored_dataflow AS (
    SELECT
        id_ AS "id", rev_ AS "revision",
        generated_ AS "is_generated", tenant_id_ AS "tenant_id",
        type_ AS "type", create_time_ AS "created_on", root_proc_inst_id_ AS "root_proc_inst_id",
        removal_time_ AS "deleted_on", name_ AS "name", convert_from(bytes_, 'UTF8') AS "dataflow"
    FROM act_ge_bytearray
),
stored_workflow AS (
    SELECT
        sd.*,
        CAST(sd.dataflow AS xml) AS "workflow"
    FROM stored_dataflow sd
    WHERE xml_is_well_formed_document(sd.dataflow)
    ORDER BY sd.name ASC, sd.created_on DESC
)
SELECT
    sw.*,
    xpath(xm.fetch_url_and_payload_query, sw.workflow, xm.namespaces) AS "fetch_url_and_payload",
    (xpath(xm.count_url_and_payload_query, sw.workflow, xm.namespaces))[1]::text::int AS "count_url_and_payload"
FROM stored_workflow sw
INNER JOIN xpath_metadata xm ON true
WHERE (xpath(xm.count_url_and_payload_query, sw.workflow, xm.namespaces))[1]::text::int > 0

Playground

WITH xpath_metadata AS (
    SELECT
        (
            SELECT
                array_agg(array[
                    cast(raw_xpath_namespace->>0 AS varchar),
                    cast(raw_xpath_namespace->>1 AS varchar)
            ])
            FROM jsonb_array_elements('[
                ["bpmn",    "http://www.omg.org/spec/BPMN/20100524/MODEL"],
                ["bpmndi",  "http://www.omg.org/spec/BPMN/20100524/DI"],
                ["dc",      "http://www.omg.org/spec/DD/20100524/DC"],
                ["di",      "http://www.omg.org/spec/DD/20100524/DI"],
                ["modeler", "http://camunda.org/schema/modeler/1.0"],
                ["camunda", "http://camunda.org/schema/1.0/bpmn"]
            ]'::jsonb) AS raw_xpath_namespace
        ) AS "namespaces"
        , 'count(/*/bpmn:process/*/*/*/*/camunda:inputParameter[@name="url" or @name="payload"])' AS "count_url_payload"
        , '/*/bpmn:process/*/*/*/*/camunda:inputParameter[@name="url" or @name="payload"]/text()' AS "fetch_url_payload"
        , '{"username": "admin", "password": "p@$$W0rd"}' AS "find_payload"
        , '{"username": "admin", "password": "p@55W0rd"}' AS "fill_payload"
        , 'https://staging.academia.chorke.org' AS "find_base_url"
        , 'http://chorke.local' AS "fill_base_url"
),
stored_workflow AS (
    SELECT
        '<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_0wdjv5g" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.12.0" modeler:executionPlatform="Camunda Platform" modeler:executionPlatformVersion="7.15.0">
  <bpmn:process id="create-quotation" name="Create Quotation" isExecutable="true">
    <bpmn:startEvent id="StartEvent_1">
      <bpmn:outgoing>Flow_03agry8</bpmn:outgoing>
    </bpmn:startEvent>
    <bpmn:endEvent id="Event_04jx9c3">
      <bpmn:incoming>Flow_0g38t01</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:sequenceFlow id="Flow_0g38t01" sourceRef="Activity_1ia0put" targetRef="Event_04jx9c3" />
    <bpmn:serviceTask id="Activity_1ia0put" name="Create Quotation">
      <bpmn:extensionElements>
        <camunda:connector>
          <camunda:inputOutput>
            <camunda:inputParameter name="payload">{
    "properties":{
      "version": "2",
      "Source":"B2B Portal",
      "Plan Type":"${planType}",
      "Plan":"${plan}",
      "Price":{
         "Rate":"${result.rate}",
         "Total":"${result.total}",
         "Driver Fee":"${result.driverFee}"
      },
      "Full Name":"${fullName}",
      "Nationality":"${nationality}",
      "ID Number":"${idNumber}",
      "ID Type":"${idDocType}",
      "Postcode":"${postcode}",
      "Country":"${country}"
    },
    "productSlug": "${productSlug}",
    "productName": "${productName}",
    "productCode": "${productCode}",
    "totalPremium": ${result.total}
}</camunda:inputParameter>
            <camunda:inputParameter name="url">https://staging.academia.chorke.org/services/quote/quotations/v2/${productSlug}</camunda:inputParameter>
            <camunda:inputParameter name="method">POST</camunda:inputParameter>
            <camunda:inputParameter name="headers">
              <camunda:map>
                <camunda:entry key="Accept">application/json</camunda:entry>
                <camunda:entry key="Content-Type">application/json</camunda:entry>
                <camunda:entry key="X-Auth-Token">${token}</camunda:entry>
                <camunda:entry key="X-Auth-Internal-Key">A7E6EF345E24117DCF3B586981223</camunda:entry>
              </camunda:map>
            </camunda:inputParameter>
            <camunda:outputParameter name="refCode">${JSON(response).prop("refCode").value()}</camunda:outputParameter>
            <camunda:outputParameter name="refId">${JSON(response).prop("refId").value()}</camunda:outputParameter>
          </camunda:inputOutput>
          <camunda:connectorId>http-connector</camunda:connectorId>
        </camunda:connector>
      </bpmn:extensionElements>
      <bpmn:incoming>Flow_1s5n3n6</bpmn:incoming>
      <bpmn:outgoing>Flow_0g38t01</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:sequenceFlow id="Flow_1s5n3n6" sourceRef="Activity_1u1wyzg" targetRef="Activity_1ia0put" />
    <bpmn:serviceTask id="Activity_1u1wyzg" name="Get Token">
      <bpmn:extensionElements>
        <camunda:connector>
          <camunda:inputOutput>
            <camunda:inputParameter name="payload">{"username": "admin", "password": "p@$$W0rd"}</camunda:inputParameter>
            <camunda:inputParameter name="url">https://staging.academia.chorke.org/services/auth/identity/users/login</camunda:inputParameter>
            <camunda:inputParameter name="method">POST</camunda:inputParameter>
            <camunda:inputParameter name="headers">
              <camunda:map>
                <camunda:entry key="Accept">application/json</camunda:entry>
                <camunda:entry key="Content-Type">application/json</camunda:entry>
              </camunda:map>
            </camunda:inputParameter>
            <camunda:outputParameter name="token">${S(response).prop("token").value()}</camunda:outputParameter>
          </camunda:inputOutput>
          <camunda:connectorId>http-connector</camunda:connectorId>
        </camunda:connector>
      </bpmn:extensionElements>
      <bpmn:incoming>Flow_03agry8</bpmn:incoming>
      <bpmn:outgoing>Flow_1s5n3n6</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:sequenceFlow id="Flow_03agry8" sourceRef="StartEvent_1" targetRef="Activity_1u1wyzg" />
  </bpmn:process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="create-quotation">
      <bpmndi:BPMNEdge id="Flow_1s5n3n6_di" bpmnElement="Flow_1s5n3n6">
        <di:waypoint x="360" y="210" />
        <di:waypoint x="460" y="210" />
        <di:waypoint x="460" y="140" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_0g38t01_di" bpmnElement="Flow_0g38t01">
        <di:waypoint x="510" y="100" />
        <di:waypoint x="562" y="100" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_03agry8_di" bpmnElement="Flow_03agry8">
        <di:waypoint x="208" y="100" />
        <di:waypoint x="234" y="100" />
        <di:waypoint x="234" y="210" />
        <di:waypoint x="260" y="210" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
        <dc:Bounds x="172" y="82" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Event_04jx9c3_di" bpmnElement="Event_04jx9c3">
        <dc:Bounds x="562" y="82" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Activity_00l2f3y_di" bpmnElement="Activity_1ia0put">
        <dc:Bounds x="410" y="60" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Activity_1bsx6ed_di" bpmnElement="Activity_1u1wyzg">
        <dc:Bounds x="260" y="170" width="100" height="80" />
      </bpmndi:BPMNShape>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn:definitions>'::xml AS "workflow"
)
SELECT
    (   xpath(xm.count_url_payload, sw.workflow, xm.namespaces))[1]::text::int AS "count"
    ,   xpath_exists(xm.fetch_url_payload, sw.workflow, xm.namespaces) AS "exists"
    ,   xpath(xm.fetch_url_payload, sw.workflow, xm.namespaces) AS "fetch"
    ,   sw.workflow::text as "old_workflow"
    ,   replace(
            replace(sw.workflow::text, xm.find_base_url, xm.fill_base_url)
            , xm.find_payload
            , xm.fill_payload
        ) AS "new_workflow"
FROM stored_workflow sw
INNER JOIN xpath_metadata xm ON true
WHERE  (xpath(xm.count_url_payload, sw.workflow, xm.namespaces))[1]::text::int > 0

Knowledge

sudo snap install docker
sudo apt  install docker-compose
fedora: alter config
sudo alternatives --config java
sudo alternatives --config javac

debian: alter config
sudo update-alternatives --config java
sudo update-alternatives --config javac
rm -rf $HOME/.m2/repository/org/jetbrains/
rm -rf $HOME/.m2/repository/org/apache/tomcat/embed/tomcat-embed-core/
camunda: download bpmn
processEngine().getRepositoryService().createProcessDefinitionQuery().list();
processEngine().getRepositoryService().getProcessModel("someID");
sudo update-alternatives --remove-all camunda-modeler
docker login hub.chorke.org -u academia -p sadaqah!
docker pull camunda/camunda-bpm-platform:run-latest
docker run -d --name camunda -p 8080:8080 camunda/camunda-bpm-platform:run-latest
docker tag academia-bpmn:latest reg.chorke.org/academia-bpmn:latest
docker push reg.chorke.org/academia-bpmn:latest
docker rmi reg.chorke.org/academia-bpmn:latest

docker pull hub.chorke.org/academia-bpmn:latest
docker rmi hub.chorke.org/academia-bpmn:latest

References