Inhaltsverzeichnis

Camunda ist ein kostenloses BPM tool. Es unterstützt CMMN sowie DMN. Ausserdem unterstützt es externe Tasks mit Hilfe von z.B SOAP oder integrierter REST API. Siehe REST

Integration mit OpenKM Api möglich. (CMIS specification)

Mit Hilfe des Java Spring Framework ist es einfach, eigenständige Programme für Geschäftspraktiken- und abläufe zu entwickeln.

Um ein Berechtigungskonzept zu implementieren muss das Authorisation service aktiviert werden! Besser ist eine direkte Anbindung an LDAP. Siehe auch https://forum.camunda.io/t/how-to-setup-ldap-in-camunda-platform-run/26553

Increase max-file-size - NOT with Camunda Run? - Siehe Frage im Forum.

Usertask embedded form Docs - reference using

embedded:deployment:form.html

external-task-client-js dok

Spring Boot example project

Download archive

Minimal history Plugin

Authorization

MySQL Setup

Connect Camunda to MySQL Database instead of H2

Spring Boot right MySQL Driver Installation und connection

CMMN

Um im Camunda modeler das CMMN Modul zu aktivieren startet man das Programm mit dem Parameter

--no-disable-cmmn

DMN

DMN (Decision making notation) ist eine Auszeichnungssprache für automatisierte Entscheidungen.

Evaluate a decision via REST api

Installation

Docker

Camunda Run 7

docker pull camunda/camunda-bpm-platform:latest
docker run -d --name camunda -p 8080:8080 camunda/camunda-bpm-platform:latest
docker container start camunda
docker container stop camunda

Camunda Platform 8

git clone https://github.com/camunda/docker-camunda-bpm-platform
cd docker-camunda-bpm-platform
docker compose up -d

REST API

Authentication

In file

$CAMUNDA_HOME/server/apache-tomcat/webapps/engine-rest/WEB-INF/web.xml

uncomment the lines for basic auth.

deploy a process

POST localhost:8080/engine-rest/deployment/create
Content-Type: multipart/formdata
file: upload

Evaluate a process/decision



start a process

POST localhost:8080/engine-rest/process-definition/key/[process-name]/start
Content-Type: application/json
Raw: { /* some initial parameters */ }

Assign a running task to a user

POST localhost:8080/engine-rest/task/[task-id]/assignee
Content-Type: application/json
data: {"userId": "[user-id]"}

Get variables from a running task

GET localhost:8080/engine-rest/task/[task-id]/variables

delete a started task

DELETE localhost:8080/engine-rest/process-instance/[process-instance-id]

delete a deployed process

DELETE localhost:8080/engine-rest/process-definition/key/[process-name]

Scripting

Python

pip install camunda-external-task-client-python3
import logging

from camunda.external_task.external_task_worker import ExternalTaskWorker
from examples.task_handler_example import handle_task

logger = logging.getLogger(__name__)

default_config = {
    "maxTasks": 1,
    "lockDuration": 10000,
    "asyncResponseTimeout": 0,
    "isDebug": False,
}


def main():
    #configure_logging()
    while 1:
        try: 
            ExternalTaskWorker(worker_id=1, config=default_config).fetch_and_execute(topic_names=["SendLetter"], action=handle_task)
        except:
            print("No tasks found")

def configure_logging():
    logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s", handlers=[logging.StreamHandler()])


if __name__ == '__main__':
    main()

Pure REST

import requests
import json
import time

url = 'http://localhost:8080/engine-rest/execution'
task = {}
 
try:
    res = requests.post(url, json=task)
    #print(res.status_code)
    body = res.text        
            
except: 
    print('The engine seems to be down.')


while body == '[]':
    res = requests.post(url, json=task)
    time.sleep(5)    
    if body != '[]':
        break

response = json.loads(body)
        
print(response[0]['id'])

NodeJS

Siehe Camunda External Task NodeJS - Github

npm install -s camunda-external-task-client-js
npm install -s mysql
const { Client, logger } = require("camunda-external-task-client-js");
const { Variables } = require("camunda-external-task-client-js");

const config = { baseUrl: "http://localhost:8080/engine-rest" };
const client = new Client(config);
 
// using mysql database
var mysql = require('mysql'); 

var con = mysql.createConnection({
  host: "localhost",
  user: "root",
  database: "test",
  password: ""
});

con.connect(function(err) {
  console.log("Connected!");
  con.query("SELECT * FROM books;", function (err, result) {
    for(var i = 0; i < result.length; i++)
		console.log("Result: " + result[i]['title']);
  });
}); 

client.subscribe("Rechnung", async function({ task, taskService }) {

  console.log("*** Processing task " + task.id);
  
  var uploadedFile = task.variables.get("rechnung");
    
  const http = require('http');
  const fs = require('fs');

  const file = fs.createWriteStream("C:/Users/mzarat/Desktop/" + task.id + "_test.pdf");
  
  const request = http.get("http://localhost:8080/engine-rest" + uploadedFile.remotePath, function(response) {
	
	response.pipe(file);

	// after download completed close filestream
	file.on("finish", () => {
       file.close();
       console.log("*** The file was saved at C:/Users/mzarat/Desktop/" + task.id + "_test.pdf");
	});
  });
  
  const processVariables = new Variables();
  
  //processVariables.set("testIndex", "1");

  // complete the task
  await taskService.complete(task, processVariables);
  
  //console.log("*** Task " + task.id + " completed.");
  
});

Embedded task form

Wird im Modeler als zusätzliche Datei geaddet und referenziert mit

embedded:deployment:file.html
Die Variablen Typen (String, Double,…) müssen Groß geschrieben sein!!!!!
<form role="form" name="form">

    <div class="form-group">
  
        <label for="customerId-field">Grund</label>
        <input required cam-variable-name="grund" cam-variable-type="String" class="form-control" />
		   
    </div>
	
    <div class="form-group">
	
        <label for="amount-field">Betrag</label>
        <input cam-variable-name="betrag" cam-variable-type="Double" class="form-control" />
		   
    </div>
    
    <div class="form-group">
	
        <label for="amount-field">Betrag</label>
        <select cam-variable-name="type" cam-variable-type="String">
            <option value="Wissen">Wissen</option>
            <option value="Technik">Technik</option>
            <option value="Medikament">Medikament</option>
        </select>
		   
    </div>
    
    <div class="form-group">
    
        <input type="checkbox" cam-variable-name="bool" cam-variable-type="Boolean">
        <label for="vehicle1"> I have a bike</label>
        
    </div>
	
</form>

Javascript Zugriff auf Prozess Variablen

<form role="form" name="form">
    <div class="form-group">
        <label for="stefan-field">Stefan</label>
        <input id="stefan-field" required cam-variable-name="stefan" cam-variable-type="Boolean" class="form-control" />
		
		<label for="walter-field">Walter</label>
        <input id="walter-field" required cam-variable-name="walter" cam-variable-type="Boolean" class="form-control" />
		
		<div id="variable-output"></div>
    </div>
	
	<script cam-script type="text/form-script">
        /* Das braucht man nur wenn die variablen noch nicht im formular verwendet werden!
		camForm.on('form-loaded', function() {
            camForm.variableManager.fetchVariable('walter');
            camForm.variableManager.fetchVariable('stefan');
        });
		*/
        camForm.on('variables-fetched', function() {
            $scope.walter = camForm.variableManager.variable('walter').value;
            $scope.stefan = camForm.variableManager.variable('stefan').value;
        });
    </script>

    <p>{{stefan}}</p>
    <p>{{walter}}</p>
	
</form>