Upload diagrams from your Camunda via API

Создано: Denis Kotov, Изменено Wed, 29 Mar 2023 на 01:33 PM по Denis Kotov

For some use cases (for example single source of truth about all  your processes in Camunda) you can easly upload diagrams from your backend to Storm.  To achive that you need:


1. Get API KEY

2. Send POST request to https://stormbpmn.com/public-api/v1/upload-diagrams (or your <server-url>/public-api/v1/upload-diagrams for enterprise customers)

3. Add HEADER "X-Api-Key"  with your api key, that you receivedin 1 step.

4.  Generate BODY for your request. Storm accept JSON Array with structure:

  • id* - process ID in YOUR system
  • xml*- valid xml (in .bpmn format). All xml symbols must be escaped.
  • name* - process name.  Storm try find procesess with EXACTLY (Case-sensitive, whitespace sensitive etc) name to update process 
  • source - additional field, that help people in Storm to understand source of diagram or version.

For example:

     [
     {
        "id":  "Meeting Scheduling:1:1123",
        "xml": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<bpmn:definitions xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" 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:di=\"http://www.omg.org/spec/DD/20100524/DI\" xmlns:storm=\"http://storm.bpmn2.ru/ns\" id=\"Definitions_1k3dlqi\" targetNamespace=\"http://bpmn.io/schema/bpmn\">\n  <bpmn:process id=\"Process_1\" isExecutable=\"false\">\n    <bpmn:startEvent id=\"StartEvent_1\">\n      <bpmn:outgoing>SequenceFlow_1cqyhs3</bpmn:outgoing>\n    </bpmn:startEvent>\n    <bpmn:endEvent id=\"EndEvent_0zk83sa\">\n      <bpmn:incoming>Flow_01sknpp</bpmn:incoming>\n    </bpmn:endEvent>\n    <bpmn:sequenceFlow id=\"SequenceFlow_1cqyhs3\" sourceRef=\"StartEvent_1\" targetRef=\"Activity_0yu8ycq\" />\n    <bpmn:sequenceFlow id=\"Flow_01sknpp\" sourceRef=\"Activity_0yu8ycq\" targetRef=\"EndEvent_0zk83sa\" />\n    <bpmn:userTask id=\"Activity_0yu8ycq\" storm:HTMLDescription=\"&#60;p&#62;Процесс с &#38;nbsp;описанием&#60;/p&#62;\" storm:StormUrl=\"null\">\n      <bpmn:incoming>SequenceFlow_1cqyhs3</bpmn:incoming>\n      <bpmn:outgoing>Flow_01sknpp</bpmn:outgoing>\n    </bpmn:userTask>\n  </bpmn:process>\n  <bpmndi:BPMNDiagram id=\"BPMNDiagram_1\">\n    <bpmndi:BPMNPlane id=\"BPMNPlane_1\" bpmnElement=\"Process_1\">\n      <bpmndi:BPMNEdge id=\"Flow_01sknpp_di\" bpmnElement=\"Flow_01sknpp\">\n        <di:waypoint x=\"240\" y=\"410\" />\n        <di:waypoint x=\"311\" y=\"410\" />\n        <di:waypoint x=\"311\" y=\"179\" />\n        <di:waypoint x=\"381\" y=\"179\" />\n      </bpmndi:BPMNEdge>\n      <bpmndi:BPMNEdge id=\"SequenceFlow_1cqyhs3_di\" bpmnElement=\"SequenceFlow_1cqyhs3\">\n        <di:waypoint x=\"-42\" y=\"179\" />\n        <di:waypoint x=\"49\" y=\"179\" />\n        <di:waypoint x=\"49\" y=\"410\" />\n        <di:waypoint x=\"140\" y=\"410\" />\n      </bpmndi:BPMNEdge>\n      <bpmndi:BPMNShape id=\"_BPMNShape_StartEvent_2\" bpmnElement=\"StartEvent_1\">\n        <dc:Bounds x=\"-78\" y=\"161\" width=\"36\" height=\"36\" />\n      </bpmndi:BPMNShape>\n      <bpmndi:BPMNShape id=\"EndEvent_0zk83sa_di\" bpmnElement=\"EndEvent_0zk83sa\">\n        <dc:Bounds x=\"381\" y=\"161\" width=\"36\" height=\"36\" />\n      </bpmndi:BPMNShape>\n      <bpmndi:BPMNShape id=\"Activity_13afhcv_di\" bpmnElement=\"Activity_0yu8ycq\">\n        <dc:Bounds x=\"140\" y=\"370\" width=\"100\" height=\"80\" />\n      </bpmndi:BPMNShape>\n    </bpmndi:BPMNPlane>\n  </bpmndi:BPMNDiagram>\n</bpmn:definitions>\n",
        "name": "Meetings",
        "source": "CamundaMeetingsBackend"
    }
    ]

5. Recive response and do whatever you want with that. Response structure is:

  • errors.emptyName - ID of process from request, that have empty name.
  • errors.emptyDefintion- ID of process from request, that have empty xml.
  • errors.notXml- ID of process from request, that have something different from bpmn xml format in xml field.
  • createdDiagrams[] - array of created processes in Storm.
    • stormDiagramId - process id in Storm.
    • sourceDiagramId - ID from your request.
  • updatedDiagrams[] - array of updated  processes in Storm. Structure same as above.


Exaple response:

{
    "errors": {
        "emptyName": [],
        "emptyDefinition": [],
        "notXml": []
    },
    "createdDiagrams": [],
    "updatedDiagrams": [
        {
            "stormDiagramId": "94d2e63f-f84a-40d4-b4a3-592b0cc7c7d9",
            "sourceDiagramId": "rhsrthsrth"
        }
    ]
}

Uploaded process will have that kind of description in Storm:


Important info  (valid only for SAAS, enterprise customers can configure it):


- Version and diagrams created with team admin username.

- Maximum diagrams in one request - 20.

- Diagrams with same id updated in request order,   so you can upload diffrent versions of same diagram for version history in one request.

- Name field is critical to update your diagrams,  never change it in Storm, if you want update it from your backend.

- Default rate limit  - 5 requests in 1 minute.  You can find remaining request in each response header X-Rate-Limit-Remaining.

- Default size of 1 request - 10 Mb. You cannot upload more in one request. 

If you reach your quota you will get that message:

{
    "timestamp": "2022-06-28T12:03:03.438+00:00",
    "status": 429,
    "error": "Too Many Requests",
    "message": "You have exhausted your API Request Quota",
    "path": "/public-api/v1/upload-diagrams"
}

In response header X-Rate-Limit-Retry-After-Seconds you can find how much second you need wait before another try. If you reach your limit more that 3 times in 24 hour, you api key will be banned forever (but if you really need more or something bad happens, write us via email storm@bpmn2.ru, we will help).




Here a shell script example for camunda-based repositories:


#!/bin/bash
# Going to build folder and reading all bpmn file
files=($(ls ./src/main/resources/bpmn/*.bpmn))
size=${#files[@]}
echo '[' > temp.json
counter=1
# Starting temp curl body file
echo Starting loop
# taking file by file
for file in ${files[*]}; do
  id="$(grep -Po '(?<=<bpmn:process\sid=")[^"]+' $file)"
  content="$(cat $file | sed 's/"/\\"/g;')"
  name="$(basename $file .bpmn)"
  echo '{"id":"'$id'","xml":"'$content'", "name": "'$name'", "source": "app"}' >> temp.json
  # Commas between objects shouldn't go at the end of the list
  if ((counter % 20)) && ((size != counter)) ; then
    echo ',' >> temp.json
  fi
  # The limit of the API is 20 diagrams for request
  if ! ((counter % 20)); then
    echo ']' >> temp.json
    curl -X POST -H "X-Api-Key: API-KEY" -H "Content-Type: application/json" -d @temp.json stormbpmn.com/public-api/v1/upload-diagrams -i
    rm temp.json
    echo '[' > temp.json
  fi
  ((counter=counter+1))
  # Limitation of the API, no more then 5 request per minute
  if ((counter > 100)); then
    sleep 60
  fi
done
# Starting temp curl body file
# In cases when number of diagrams is not even to 20 we have to send the rest
echo ']' >> temp.json
curl -X POST -H "X-Api-Key: API_KEY" -H "Content-Type: application/json" -d @temp.json stormbpmn.com/public-api/v1/upload-diagrams -i
rm temp.json


Статья помогла?

Отлично!

Спасибо за ваш отзыв

Извините, что не удалось помочь!

Спасибо за ваш отзыв

Расскажите, как мы можем улучшить эту статью!

Выберите хотя бы одну причину
Требуется проверка CAPTCHA.

Комментарий отправлен

Мы ценим вашу помощь и постараемся исправить статью