Skip to content

Instantly share code, notes, and snippets.

@tomlarkworthy
Last active May 13, 2020 12:33
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tomlarkworthy/c0d50934b1db2e6d3ddfb719b6342db1 to your computer and use it in GitHub Desktop.
Save tomlarkworthy/c0d50934b1db2e6d3ddfb719b6342db1 to your computer and use it in GitHub Desktop.
Camunda at-least-once delivery
<?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:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_0cqopu9" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.7.0">
<bpmn:process id="Echo" name="Echo" isExecutable="true">
<bpmn:startEvent id="StartEvent_1">
<bpmn:outgoing>Flow_0fjxlkl</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:sequenceFlow id="Flow_0fjxlkl" sourceRef="StartEvent_1" targetRef="Gateway_0mt3mgo" />
<bpmn:callActivity id="PushPubsub" name="Publish Echo" camunda:asyncBefore="true" camunda:asyncAfter="true" camunda:exclusive="false" camunda:jobPriority="1" calledElement="PubsubPublish">
<bpmn:extensionElements>
<camunda:in businessKey="#{execution.processBusinessKey}" />
<camunda:in source="topic" target="topic" />
<camunda:in source="project" target="project" />
<camunda:in source="message" target="message" />
<camunda:inputOutput>
<camunda:inputParameter name="topic">myTopic</camunda:inputParameter>
<camunda:inputParameter name="project">larkworthy-tester</camunda:inputParameter>
<camunda:inputParameter name="message">
<camunda:script scriptFormat="groovy">import groovy.json.JsonOutput
JsonOutput.toJson([
messageName: "echo",
businessKey: execution.processBusinessKey,
processInstanceId: execution.processInstanceId
])</camunda:script>
</camunda:inputParameter>
</camunda:inputOutput>
<camunda:failedJobRetryTimeCycle>R999999/PT30S</camunda:failedJobRetryTimeCycle>
</bpmn:extensionElements>
<bpmn:incoming>Flow_0zou8kx</bpmn:incoming>
<bpmn:outgoing>Flow_1cyjot4</bpmn:outgoing>
</bpmn:callActivity>
<bpmn:receiveTask id="Activity_0avp8zm" name="Wait for Echo" camunda:jobPriority="2" messageRef="Message_0aqvsvq">
<bpmn:incoming>Flow_0at5xd4</bpmn:incoming>
<bpmn:outgoing>Flow_0i6u2tm</bpmn:outgoing>
</bpmn:receiveTask>
<bpmn:endEvent id="Event_0aw4vxw">
<bpmn:incoming>Flow_10kjc16</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_0zou8kx" sourceRef="Gateway_0mt3mgo" targetRef="PushPubsub" />
<bpmn:sequenceFlow id="Flow_0at5xd4" sourceRef="Gateway_0mt3mgo" targetRef="Activity_0avp8zm" />
<bpmn:parallelGateway id="Gateway_0mt3mgo">
<bpmn:incoming>Flow_0fjxlkl</bpmn:incoming>
<bpmn:outgoing>Flow_0zou8kx</bpmn:outgoing>
<bpmn:outgoing>Flow_0at5xd4</bpmn:outgoing>
</bpmn:parallelGateway>
<bpmn:sequenceFlow id="Flow_0i6u2tm" sourceRef="Activity_0avp8zm" targetRef="Gateway_0mblpjs" />
<bpmn:sequenceFlow id="Flow_10kjc16" sourceRef="Gateway_0mblpjs" targetRef="Event_0aw4vxw" />
<bpmn:parallelGateway id="Gateway_0mblpjs">
<bpmn:incoming>Flow_0i6u2tm</bpmn:incoming>
<bpmn:incoming>Flow_1cyjot4</bpmn:incoming>
<bpmn:outgoing>Flow_10kjc16</bpmn:outgoing>
</bpmn:parallelGateway>
<bpmn:sequenceFlow id="Flow_1cyjot4" sourceRef="PushPubsub" targetRef="Gateway_0mblpjs" />
</bpmn:process>
<bpmn:message id="Message_0aqvsvq" name="echo" />
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Echo">
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
<dc:Bounds x="152" y="162" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_0fjxlkl_di" bpmnElement="Flow_0fjxlkl">
<di:waypoint x="188" y="180" />
<di:waypoint x="205" y="180" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="Activity_15rku3g_di" bpmnElement="PushPubsub">
<dc:Bounds x="280" y="80" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_0psem4g_di" bpmnElement="Activity_0avp8zm">
<dc:Bounds x="280" y="210" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_0aw4vxw_di" bpmnElement="Event_0aw4vxw">
<dc:Bounds x="472" y="162" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_0zou8kx_di" bpmnElement="Flow_0zou8kx">
<di:waypoint x="230" y="155" />
<di:waypoint x="230" y="120" />
<di:waypoint x="280" y="120" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0at5xd4_di" bpmnElement="Flow_0at5xd4">
<di:waypoint x="230" y="205" />
<di:waypoint x="230" y="250" />
<di:waypoint x="280" y="250" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="Gateway_12c8goe_di" bpmnElement="Gateway_0mt3mgo">
<dc:Bounds x="205" y="155" width="50" height="50" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_0i6u2tm_di" bpmnElement="Flow_0i6u2tm">
<di:waypoint x="380" y="250" />
<di:waypoint x="430" y="250" />
<di:waypoint x="430" y="205" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_10kjc16_di" bpmnElement="Flow_10kjc16">
<di:waypoint x="455" y="180" />
<di:waypoint x="472" y="180" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="Gateway_1kucqok_di" bpmnElement="Gateway_0mblpjs">
<dc:Bounds x="405" y="155" width="50" height="50" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_1cyjot4_di" bpmnElement="Flow_1cyjot4">
<di:waypoint x="380" y="120" />
<di:waypoint x="430" y="120" />
<di:waypoint x="430" y="155" />
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>
import axios from 'axios';
import PubSub = require("@google-cloud/pubsub");
const axiosConfig = {
validateStatus: (status: number) =>
(status >= 200 && status < 300) // default
// If a response gets delivered twice, then the second message will not correspond
// to a receive task in Camunda, and the engine will reject the delivery with a
// 400 "Cannot correlate message '<msg> ....':
// We DO NOT want to retry this, it will never succeed, so mark it as a success
// So the retry behaviour of GCF does not go into a loop
// Note other 4xx errors like a 429, are Cloud Run or Cloud SQL being busy
// Which we do want to retry. 400 is the MVP for at-least-once
|| status == 400
}
export async function echo(event: PubSub.Message, context: any) {
// @ts-ignore (Buffers work fine with JSON parse)
const payload = JSON.parse(Buffer.from(event.data, 'base64'));
console.log("Received: " + JSON.stringify(payload));
const url = process.env.MESSAGE_URL;
if (url === undefined) throw new Error("Must defined MESSAGE_URL env variable");
// Send to Camunda
// https://docs.camunda.org/manual/7.5/reference/rest/message/post-message/#example
const response = await axios.post(url, payload, axiosConfig); // Send message to Camunda
console.log("Camunda response:", response.status)
};
<?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:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_14ku8kk" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.7.0">
<bpmn:process id="Process_06543vc" name="EchoLoop" isExecutable="true">
<bpmn:startEvent id="StartEvent_1">
<bpmn:outgoing>Flow_0wm79yr</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:callActivity id="Activity_0z28vmt" name="Echo" calledElement="Echo">
<bpmn:incoming>Flow_1hovmhq</bpmn:incoming>
<bpmn:incoming>Flow_0wm79yr</bpmn:incoming>
<bpmn:outgoing>Flow_1hovmhq</bpmn:outgoing>
</bpmn:callActivity>
<bpmn:sequenceFlow id="Flow_1hovmhq" sourceRef="Activity_0z28vmt" targetRef="Activity_0z28vmt" />
<bpmn:sequenceFlow id="Flow_0wm79yr" sourceRef="StartEvent_1" targetRef="Activity_0z28vmt" />
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_06543vc">
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
<dc:Bounds x="182" y="62" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_05k2xqr_di" bpmnElement="Activity_0z28vmt">
<dc:Bounds x="250" y="57" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_1hovmhq_di" bpmnElement="Flow_1hovmhq">
<di:waypoint x="300" y="137" />
<di:waypoint x="300" y="157" />
<di:waypoint x="230" y="157" />
<di:waypoint x="230" y="100" />
<di:waypoint x="250" y="100" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0wm79yr_di" bpmnElement="Flow_0wm79yr">
<di:waypoint x="218" y="80" />
<di:waypoint x="250" y="80" />
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>
<?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:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_0gmvjgr" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.7.0">
<bpmn:process id="FetchToken" name="FetchToken" isExecutable="true">
<bpmn:startEvent id="StartEvent_1">
<bpmn:outgoing>Flow_0plrjc8</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:serviceTask id="Activity_08v9fhc" name="GetToken">
<bpmn:extensionElements>
<camunda:connector>
<camunda:inputOutput>
<camunda:inputParameter name="url">http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token</camunda:inputParameter>
<camunda:inputParameter name="headers">
<camunda:map>
<camunda:entry key="Metadata-Flavor">Google</camunda:entry>
</camunda:map>
</camunda:inputParameter>
<camunda:inputParameter name="method">GET</camunda:inputParameter>
<camunda:outputParameter name="token">
<camunda:script scriptFormat="groovy">import groovy.json.JsonSlurper
def jsonSlurper = new JsonSlurper()
def object = jsonSlurper.parseText(response)
object.access_token</camunda:script>
</camunda:outputParameter>
</camunda:inputOutput>
<camunda:connectorId>http-connector</camunda:connectorId>
</camunda:connector>
</bpmn:extensionElements>
<bpmn:incoming>Flow_0plrjc8</bpmn:incoming>
<bpmn:outgoing>Flow_18s8udj</bpmn:outgoing>
</bpmn:serviceTask>
<bpmn:sequenceFlow id="Flow_0plrjc8" sourceRef="StartEvent_1" targetRef="Activity_08v9fhc" />
<bpmn:endEvent id="Event_0jsmp0r">
<bpmn:incoming>Flow_18s8udj</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_18s8udj" sourceRef="Activity_08v9fhc" targetRef="Event_0jsmp0r" />
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="FetchToken">
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
<dc:Bounds x="152" y="99" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_08v9fhc_di" bpmnElement="Activity_08v9fhc">
<dc:Bounds x="210" y="77" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_0plrjc8_di" bpmnElement="Flow_0plrjc8">
<di:waypoint x="188" y="117" />
<di:waypoint x="210" y="117" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="Event_0jsmp0r_di" bpmnElement="Event_0jsmp0r">
<dc:Bounds x="332" y="99" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_18s8udj_di" bpmnElement="Flow_18s8udj">
<di:waypoint x="310" y="117" />
<di:waypoint x="332" y="117" />
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>
<?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" id="Definitions_0p2sks3" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.7.0">
<bpmn:process id="Http" name="Http" isExecutable="true">
<bpmn:startEvent id="HttpRequest">
<bpmn:outgoing>Flow_1b8ogdn</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:sequenceFlow id="Flow_1b8ogdn" sourceRef="HttpRequest" targetRef="HttpCall" />
<bpmn:serviceTask id="HttpCall" name="HttpCall">
<bpmn:extensionElements>
<camunda:connector>
<camunda:inputOutput>
<camunda:inputParameter name="url">${url}</camunda:inputParameter>
<camunda:inputParameter name="headers">
<camunda:script scriptFormat="groovy">execution.hasVariable("headers") ? execution.getVariable("headers"): []</camunda:script>
</camunda:inputParameter>
<camunda:inputParameter name="method">
<camunda:script scriptFormat="groovy">execution.hasVariable("method") ? execution.getVariable("method") : "GET"</camunda:script>
</camunda:inputParameter>
<camunda:inputParameter name="payload">
<camunda:script scriptFormat="groovy">execution.hasVariable("payload") ? execution.getVariable("payload") : null</camunda:script>
</camunda:inputParameter>
<camunda:outputParameter name="response">${response}</camunda:outputParameter>
<camunda:outputParameter name="statusCode">
<camunda:script scriptFormat="groovy">statusCode.toInteger()</camunda:script>
</camunda:outputParameter>
<camunda:outputParameter name="headers">
<camunda:map />
</camunda:outputParameter>
</camunda:inputOutput>
<camunda:connectorId>http-connector</camunda:connectorId>
</camunda:connector>
</bpmn:extensionElements>
<bpmn:incoming>Flow_1b8ogdn</bpmn:incoming>
<bpmn:outgoing>Flow_0emzhvb</bpmn:outgoing>
</bpmn:serviceTask>
<bpmn:endEvent id="HttpCallSuccess">
<bpmn:extensionElements>
<camunda:inputOutput>
<camunda:inputParameter name="response">${response}</camunda:inputParameter>
<camunda:inputParameter name="headers">
<camunda:map />
</camunda:inputParameter>
<camunda:inputParameter name="statusCode">${statusCode}</camunda:inputParameter>
</camunda:inputOutput>
</bpmn:extensionElements>
<bpmn:incoming>happyPath</bpmn:incoming>
</bpmn:endEvent>
<bpmn:exclusiveGateway id="HandleStatusCode" name="&#10;&#10;StatusCode">
<bpmn:incoming>Flow_0emzhvb</bpmn:incoming>
<bpmn:outgoing>happyPath</bpmn:outgoing>
<bpmn:outgoing>errorPath</bpmn:outgoing>
</bpmn:exclusiveGateway>
<bpmn:sequenceFlow id="happyPath" name="&#60; 400&#10;&#10;" sourceRef="HandleStatusCode" targetRef="HttpCallSuccess">
<bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">${statusCode &lt; 400}</bpmn:conditionExpression>
</bpmn:sequenceFlow>
<bpmn:sequenceFlow id="errorPath" name="&#62;= 400&#10;&#10;" sourceRef="HandleStatusCode" targetRef="Activity_14q0vuf">
<bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">${statusCode &gt;= 400}</bpmn:conditionExpression>
</bpmn:sequenceFlow>
<bpmn:endEvent id="Event_0ynz78o">
<bpmn:incoming>Flow_18s8q45</bpmn:incoming>
<bpmn:errorEventDefinition id="ErrorEventDefinition_0ana5hj" errorRef="Error_03ryv1t" />
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_0emzhvb" sourceRef="HttpCall" targetRef="HandleStatusCode" />
<bpmn:sequenceFlow id="Flow_18s8q45" sourceRef="Activity_14q0vuf" targetRef="Event_0ynz78o" />
<bpmn:scriptTask id="Activity_14q0vuf" scriptFormat="groovy">
<bpmn:incoming>errorPath</bpmn:incoming>
<bpmn:outgoing>Flow_18s8q45</bpmn:outgoing>
<bpmn:script>println "Error in http"</bpmn:script>
</bpmn:scriptTask>
</bpmn:process>
<bpmn:error id="Error_03ryv1t" name="HttpError" errorCode="${statusCode}" camunda:errorMessage="${S(response).prop(&#39;error&#39;).prop(&#39;message&#39;).value()}" />
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Http">
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="HttpRequest">
<dc:Bounds x="160" y="99" width="0" height="53" />
<bpmndi:BPMNLabel>
<dc:Bounds x="279" y="142" width="62" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_1b8ogdn_di" bpmnElement="Flow_1b8ogdn">
<di:waypoint x="160" y="126" />
<di:waypoint x="190" y="126" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="Activity_0c5df4n_di" bpmnElement="HttpCall">
<dc:Bounds x="190" y="86" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_17qzv6v_di" bpmnElement="HttpCallSuccess">
<dc:Bounds x="502" y="108" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Gateway_0tipgat_di" bpmnElement="HandleStatusCode" isMarkerVisible="true">
<dc:Bounds x="305" y="101" width="50" height="50" />
<bpmndi:BPMNLabel>
<dc:Bounds x="301" y="60" width="58" height="40" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_0tbsszj_di" bpmnElement="happyPath">
<di:waypoint x="355" y="126" />
<di:waypoint x="502" y="126" />
<bpmndi:BPMNLabel>
<dc:Bounds x="416" y="108" width="28" height="40" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0h9xh68_di" bpmnElement="errorPath">
<di:waypoint x="330" y="151" />
<di:waypoint x="330" y="220" />
<di:waypoint x="380" y="220" />
<bpmndi:BPMNLabel>
<dc:Bounds x="312" y="230" width="35" height="40" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="Event_0a1fxat_di" bpmnElement="Event_0ynz78o">
<dc:Bounds x="502" y="202" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_0emzhvb_di" bpmnElement="Flow_0emzhvb">
<di:waypoint x="290" y="126" />
<di:waypoint x="305" y="126" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_18s8q45_di" bpmnElement="Flow_18s8q45">
<di:waypoint x="480" y="220" />
<di:waypoint x="502" y="220" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="Activity_026djph_di" bpmnElement="Activity_14q0vuf">
<dc:Bounds x="380" y="180" width="100" height="80" />
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>
<?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:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_1608m3e" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.7.0">
<bpmn:process id="PubsubPublish" name="PubsubPublish" isExecutable="true">
<bpmn:startEvent id="StartEvent_1">
<bpmn:extensionElements>
<camunda:formData>
<camunda:formField id="project" label="project" type="string" defaultValue="larkworthy-tester" />
<camunda:formField id="topic" label="topic" type="string" defaultValue="out" />
<camunda:formField id="message" label="message" type="string" defaultValue="hello world" />
</camunda:formData>
</bpmn:extensionElements>
<bpmn:outgoing>Flow_1bc5zu8</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:callActivity id="FetchToken" name="FetchToken" calledElement="FetchToken">
<bpmn:extensionElements>
<camunda:out source="token" target="token" />
<camunda:inputOutput>
<camunda:outputParameter name="token">${token}</camunda:outputParameter>
</camunda:inputOutput>
</bpmn:extensionElements>
<bpmn:incoming>Flow_1bc5zu8</bpmn:incoming>
<bpmn:outgoing>Flow_0utyh8l</bpmn:outgoing>
</bpmn:callActivity>
<bpmn:sequenceFlow id="Flow_1bc5zu8" sourceRef="StartEvent_1" targetRef="FetchToken" />
<bpmn:endEvent id="Event_1875zce">
<bpmn:incoming>Flow_02l13be</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_02l13be" sourceRef="Activity_1jw7b7e" targetRef="Event_1875zce" />
<bpmn:callActivity id="Activity_1jw7b7e" name="publish" calledElement="Http">
<bpmn:extensionElements>
<camunda:in source="headers" target="headers" />
<camunda:in sourceExpression="https://pubsub.googleapis.com/v1/projects/${project}/topics/${topic}:publish" target="url" />
<camunda:in sourceExpression="POST" target="method" />
<camunda:inputOutput>
<camunda:inputParameter name="headers">
<camunda:script scriptFormat="groovy">[
Authorization: "Bearer " + token
]</camunda:script>
</camunda:inputParameter>
<camunda:inputParameter name="payload">
<camunda:script scriptFormat="groovy">import groovy.json.JsonOutput
import java.util.Base64
def encoded = Base64.getEncoder().encodeToString(message.getBytes());
JsonOutput.toJson([
messages: [
data: encoded
]
])</camunda:script>
</camunda:inputParameter>
</camunda:inputOutput>
<camunda:out source="response" target="response" />
<camunda:out source="statusCode" target="statusCode" />
<camunda:out source="headers" target="headers" />
<camunda:in source="payload" target="payload" />
</bpmn:extensionElements>
<bpmn:incoming>Flow_0utyh8l</bpmn:incoming>
<bpmn:outgoing>Flow_02l13be</bpmn:outgoing>
</bpmn:callActivity>
<bpmn:boundaryEvent id="Event_0dn48ac" attachedToRef="Activity_1jw7b7e">
<bpmn:outgoing>Flow_03wrs60</bpmn:outgoing>
<bpmn:errorEventDefinition id="ErrorEventDefinition_12x769u" errorRef="Error_08tmsn2" camunda:errorCodeVariable="errorCode" camunda:errorMessageVariable="errorMessage" />
</bpmn:boundaryEvent>
<bpmn:endEvent id="Event_0ihp1t6">
<bpmn:incoming>Flow_115qfnw</bpmn:incoming>
<bpmn:errorEventDefinition id="ErrorEventDefinition_1ybjccq" errorRef="Error_0zvmets" />
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_115qfnw" sourceRef="Activity_0t1dbw7" targetRef="Event_0ihp1t6" />
<bpmn:sequenceFlow id="Flow_03wrs60" sourceRef="Event_0dn48ac" targetRef="Activity_0t1dbw7" />
<bpmn:scriptTask id="Activity_0t1dbw7" name="Log error&#10;&#10;" scriptFormat="javascript">
<bpmn:incoming>Flow_03wrs60</bpmn:incoming>
<bpmn:outgoing>Flow_115qfnw</bpmn:outgoing>
<bpmn:script>java.lang.System.err.println (errorCode + ": " + errorMessage)</bpmn:script>
</bpmn:scriptTask>
<bpmn:sequenceFlow id="Flow_0utyh8l" sourceRef="FetchToken" targetRef="Activity_1jw7b7e" />
</bpmn:process>
<bpmn:error id="Error_0zvmets" name="PublishError" errorCode="errorCode" camunda:errorMessage="errorMessage" />
<bpmn:error id="Error_08tmsn2" name="HttpError" />
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="PubsubPublish">
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
<dc:Bounds x="182" y="85" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_0itkn6y_di" bpmnElement="FetchToken">
<dc:Bounds x="250" y="60" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_1bc5zu8_di" bpmnElement="Flow_1bc5zu8">
<di:waypoint x="218" y="103" />
<di:waypoint x="250" y="103" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="Event_1875zce_di" bpmnElement="Event_1875zce">
<dc:Bounds x="502" y="82" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_02l13be_di" bpmnElement="Flow_02l13be">
<di:waypoint x="480" y="100" />
<di:waypoint x="502" y="100" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="Activity_0vwsf7v_di" bpmnElement="Activity_1jw7b7e">
<dc:Bounds x="380" y="60" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_13mp6hi_di" bpmnElement="Event_0dn48ac">
<dc:Bounds x="442" y="122" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_07y8g09_di" bpmnElement="Event_0ihp1t6">
<dc:Bounds x="502" y="202" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_115qfnw_di" bpmnElement="Flow_115qfnw">
<di:waypoint x="480" y="220" />
<di:waypoint x="502" y="220" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_03wrs60_di" bpmnElement="Flow_03wrs60">
<di:waypoint x="460" y="158" />
<di:waypoint x="460" y="180" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="Activity_1jtahg7_di" bpmnElement="Activity_0t1dbw7">
<dc:Bounds x="380" y="180" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_0utyh8l_di" bpmnElement="Flow_0utyh8l">
<di:waypoint x="350" y="100" />
<di:waypoint x="380" y="100" />
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment