Argo | -Serverless Workflow | -
---|---|
- -```yaml -apiVersion: argoproj.io/v1alpha1 -kind: Workflow -metadata: - generateName: hello-world-parameters- -spec: - entrypoint: whalesay - arguments: - parameters: - - name: message - value: hello world - - templates: - - name: whalesay - inputs: - parameters: - - name: message - container: - image: docker/whalesay - command: [cowsay] - args: ["{{inputs.parameters.message}}"] -``` - - | -- -```yaml -id: hello-world-parameters -name: Hello World with parameters -version: '1.0.0' -specVersion: '0.8' -start: whalesay -functions: -- name: whalesayimage - metadata: - image: docker/whalesay - command: cowsay -states: -- name: whalesay - type: operation - actions: - - functionRef: - refName: whalesayimage - arguments: - message: "${ .message }" - end: true -``` - - | -
Argo | -Serverless Workflow | -
---|---|
- -```yaml -apiVersion: argoproj.io/v1alpha1 -kind: Workflow -metadata: - generateName: steps- -spec: - entrypoint: hello-hello-hello - templates: - - name: hello-hello-hello - steps: - - - name: hello1 # hello1 is run before the following steps - template: whalesay - arguments: - parameters: - - name: message - value: "hello1" - - - name: hello2a # double dash => run after previous step - template: whalesay - arguments: - parameters: - - name: message - value: "hello2a" - - name: hello2b # single dash => run in parallel with previous step - template: whalesay - arguments: - parameters: - - name: message - value: "hello2b" - - name: whalesay - inputs: - parameters: - - name: message - container: - image: docker/whalesay - command: [cowsay] - args: ["{{inputs.parameters.message}}"] -``` - - | -- -```yaml -id: hello-hello-hello -name: Multi Step Hello -version: '1.0.0' -specVersion: '0.8' -start: hello1 -functions: -- name: whalesayimage - metadata: - image: docker/whalesay - command: cowsay -states: -- name: hello1 - type: operation - actions: - - functionRef: - refName: whalesayimage - arguments: - message: hello1 - transition: parallelhello -- name: parallelhello - type: parallel - completionType: allOf - branches: - - name: hello2a-branch - actions: - - functionRef: - refName: whalesayimage - arguments: - message: hello2a - - name: hello2b-branch - actions: - - functionRef: - refName: whalesayimage - arguments: - message: hello2b - end: true -``` - - | -
Argo | -Serverless Workflow | -
---|---|
- -```yaml -apiVersion: argoproj.io/v1alpha1 -kind: Workflow -metadata: - generateName: dag-diamond- -spec: - entrypoint: diamond - templates: - - name: echo - inputs: - parameters: - - name: message - container: - image: alpine:3.7 - command: [echo, "{{inputs.parameters.message}}"] - - name: diamond - dag: - tasks: - - name: A - template: echo - arguments: - parameters: [{name: message, value: A}] - - name: B - dependencies: [A] - template: echo - arguments: - parameters: [{name: message, value: B}] - - name: C - dependencies: [A] - template: echo - arguments: - parameters: [{name: message, value: C}] - - name: D - dependencies: [B, C] - template: echo - arguments: - parameters: [{name: message, value: D}] -``` - - | -- -```yaml -id: dag-diamond- -name: DAG Diamond Example -version: '1.0.0' -specVersion: '0.8' -start: A -functions: -- name: echo - metadata: - image: alpine:3.7 - command: '[echo, "{{inputs.parameters.message}}"]' -states: -- name: A - type: operation - actions: - - functionRef: - refName: echo - arguments: - message: A - transition: parallelecho -- name: parallelecho - type: parallel - completionType: allOf - branches: - - name: B-branch - actions: - - functionRef: - refName: echo - arguments: - message: B - - name: C-branch - actions: - - functionRef: - refName: echo - arguments: - message: C - transition: D -- name: D - type: operation - actions: - - functionRef: - refName: echo - arguments: - message: D - end: true -``` - - | -
Argo | -Serverless Workflow | -
---|---|
- -```yaml -apiVersion: argoproj.io/v1alpha1 -kind: Workflow -metadata: - generateName: scripts-bash- -spec: - entrypoint: bash-script-example - templates: - - name: bash-script-example - steps: - - - name: generate - template: gen-random-int-bash - - - name: print - template: print-message - arguments: - parameters: - - name: message - value: "{{steps.generate.outputs.result}}" # The result of the here-script - - - name: gen-random-int-bash - script: - image: debian:9.4 - command: [bash] - source: | # Contents of the here-script - cat /dev/urandom | od -N2 -An -i | awk -v f=1 -v r=100 '{printf "%i\n", f + r * $1 / 65536}' - - - name: gen-random-int-python - script: - image: python:alpine3.6 - command: [python] - source: | - import random - i = random.randint(1, 100) - print(i) - - - name: gen-random-int-javascript - script: - image: node:9.1-alpine - command: [node] - source: | - var rand = Math.floor(Math.random() * 100); - console.log(rand); - - - name: print-message - inputs: - parameters: - - name: message - container: - image: alpine:latest - command: [sh, -c] - args: ["echo result was: {{inputs.parameters.message}}"] -``` - - | -- -```yaml -id: scripts-bash- -name: Scripts and Results Example -version: '1.0.0' -specVersion: '0.8' -start: generate -functions: -- name: gen-random-int-bash - metadata: - image: debian:9.4 - command: bash - source: |- - cat /dev/urandom | od -N2 -An -i | awk -v f=1 -v r=100 '{printf "%i - ", f + r * $1 / 65536}' -- name: gen-random-int-python - metadata: - image: python:alpine3.6 - command: python - source: "import random \ni = random.randint(1, 100) \nprint(i)\n" -- name: gen-random-int-javascript - metadata: - image: node:9.1-alpine - command: node - source: "var rand = Math.floor(Math.random() * 100); \nconsole.log(rand);\n" -- name: printmessagefunc - metadata: - image: alpine:latest - command: sh, -c - source: 'echo result was: ${ .inputs.parameters.message }' -states: -- name: generate - type: operation - actions: - - functionRef: gen-random-int-bash - actionDataFilter: - results: "${ .results }" - transition: print-message -- name: print-message - type: operation - actions: - - functionRef: - refName: printmessagefunc - arguments: - message: "${ .results }" - end: true -``` - - | -
Argo | -Serverless Workflow | -
---|---|
- -```yaml -apiVersion: argoproj.io/v1alpha1 -kind: Workflow -metadata: - generateName: loops- -spec: - entrypoint: loop-example - templates: - - name: loop-example - steps: - - - name: print-message - template: whalesay - arguments: - parameters: - - name: message - value: "{{item}}" - withItems: # invoke whalesay once for each item in parallel - - hello world # item 1 - - goodbye world # item 2 - - - name: whalesay - inputs: - parameters: - - name: message - container: - image: docker/whalesay:latest - command: [cowsay] - args: ["{{inputs.parameters.message}}"] -``` - - | -- -```yaml -id: loops- -name: Loop over data example -version: '1.0.0' -specVersion: '0.8' -start: injectdata -functions: -- name: whalesay - metadata: - image: docker/whalesay:latest - command: cowsay -states: -- name: injectdata - type: inject - data: - greetings: - - hello world - - goodbye world - transition: printgreetings -- name: printgreetings - type: foreach - inputCollection: "${ .greetings }" - iterationParam: greeting - actions: - - name: print-message - functionRef: - refName: whalesay - arguments: - message: "${ .greeting }" - end: true -``` - - | -
Argo | -Serverless Workflow | -
---|---|
- -```yaml -apiVersion: argoproj.io/v1alpha1 -kind: Workflow -metadata: - generateName: coinflip- -spec: - entrypoint: coinflip - templates: - - name: coinflip - steps: - # flip a coin - - - name: flip-coin - template: flip-coin - # evaluate the result in parallel - - - name: heads - template: heads # call heads template if "heads" - when: "{{steps.flip-coin.outputs.result}} == heads" - - name: tails - template: tails # call tails template if "tails" - when: "{{steps.flip-coin.outputs.result}} == tails" - - # Return heads or tails based on a random number - - name: flip-coin - script: - image: python:alpine3.6 - command: [python] - source: | - import random - result = "heads" if random.randint(0,1) == 0 else "tails" - print(result) - - - name: heads - container: - image: alpine:3.6 - command: [sh, -c] - args: ["echo \"it was heads\""] - - - name: tails - container: - image: alpine:3.6 - command: [sh, -c] - args: ["echo \"it was tails\""] -``` - - | -- -```yaml -id: coinflip- -name: Conditionals Example -version: '1.0.0' -specVersion: '0.8' -start: flip-coin -functions: -- name: flip-coin-function - metadata: - image: python:alpine3.6 - command: python - source: import random result = "heads" if random.randint(0,1) == 0 else "tails" - print(result) -- name: echo - metadata: - image: alpine:3.6 - command: sh, -c -states: -- name: flip-coin - type: operation - actions: - - functionRef: flip-coin-function - actionDataFilter: - results: "${ .flip.result }" - transition: show-flip-results -- name: show-flip-results - type: switch - dataConditions: - - condition: "${ .flip | .result == \"heads\" }" - transition: show-results-heads - - condition: "${ .flip | .result == \"tails\" }" - transition: show-results-tails -- name: show-results-heads - type: operation - actions: - - functionRef: echo - actionDataFilter: - results: it was heads - end: true -- name: show-results-tails - type: operation - actions: - - functionRef: echo - actionDataFilter: - results: it was tails - end: true -``` - - | -
Argo | -Serverless Workflow | -
---|---|
- -```yaml -apiVersion: argoproj.io/v1alpha1 -kind: Workflow -metadata: - generateName: retry-backoff- -spec: - entrypoint: retry-backoff - templates: - - name: retry-backoff - retryStrategy: - limit: 10 - retryPolicy: "Always" - backoff: - duration: "1" # Must be a string. Default unit is seconds. Could also be a Duration, e.g.: "2m", "6h", "1d" - factor: 2 - maxDuration: "1m" # Must be a string. Default unit is seconds. Could also be a Duration, e.g.: "2m", "6h", "1d" - affinity: - nodeAntiAffinity: {} - container: - image: python:alpine3.6 - command: ["python", -c] - # fail with a 66% probability - args: ["import random; import sys; exit_code = random.choice([0, 1, 1]); sys.exit(exit_code)"] -``` - - | -- -```yaml -id: retry-backoff- -name: Retry Example -version: '1.0.0' -specVersion: '0.8' -start: retry-backoff -functions: -- name: fail-function - metadata: - image: python:alpine3.6 - command: python -retries: -- name: All workflow errors retry strategy - maxAttempts: 10 - delay: PT1S - maxDelay: PT1M - multiplier: 2 -states: -- name: retry-backoff - type: operation - actions: - - functionRef: - refName: flip-coin-function - arguments: - args: - - import random; import sys; exit_code = random.choice([0, 1, 1]); sys.exit(exit_code) - end: true -``` - - | -
Argo | -Serverless Workflow | -
---|---|
- -```yaml -apiVersion: argoproj.io/v1alpha1 -kind: Workflow -metadata: - generateName: coinflip-recursive- -spec: - entrypoint: coinflip - templates: - - name: coinflip - steps: - # flip a coin - - - name: flip-coin - template: flip-coin - # evaluate the result in parallel - - - name: heads - template: heads # call heads template if "heads" - when: "{{steps.flip-coin.outputs.result}} == heads" - - name: tails # keep flipping coins if "tails" - template: coinflip - when: "{{steps.flip-coin.outputs.result}} == tails" - - - name: flip-coin - script: - image: python:alpine3.6 - command: [python] - source: | - import random - result = "heads" if random.randint(0,1) == 0 else "tails" - print(result) - - - name: heads - container: - image: alpine:3.6 - command: [sh, -c] - args: ["echo \"it was heads\""] -``` - - | -- -```yaml -id: coinflip-recursive- -name: Recursion Example -version: '1.0.0' -specVersion: '0.8' -start: flip-coin-state -functions: -- name: heads-function - metadata: - image: alpine:3.6 - command: echo "it was heads" -- name: flip-coin-function - metadata: - image: python:alpine3.6 - command: python - source: import random result = "heads" if random.randint(0,1) == 0 else "tail" print(result) -states: -- name: flip-coin-state - type: operation - actions: - - functionRef: flip-coin-function - actionDataFilter: - results: "${ .steps.flip-coin.outputs.result }" - transition: flip-coin-check -- name: flip-coin-check - type: switch - dataConditions: - - condition: "${ .steps.flip-coin.outputs | .result == \"tails\" }" - transition: flip-coin-state - - condition: "${ .steps.flip-coin.outputs | .result == \"heads\" }" - transition: heads-state -- name: heads-state - type: operation - actions: - - functionRef: - refName: heads-function - arguments: - args: echo "it was heads" - end: true -``` - - | -
Argo | -Serverless Workflow | -
---|---|
- -```yaml -apiVersion: argoproj.io/v1alpha1 -kind: Workflow -metadata: - generateName: exit-handlers- -spec: - entrypoint: intentional-fail - onExit: exit-handler # invoke exit-handler template at end of the workflow - templates: - # primary workflow template - - name: intentional-fail - container: - image: alpine:latest - command: [sh, -c] - args: ["echo intentional failure; exit 1"] - - name: exit-handler - steps: - - - name: notify - template: send-email - - name: celebrate - template: celebrate - when: "{{workflow.status}} == Succeeded" - - name: cry - template: cry - when: "{{workflow.status}} != Succeeded" - - name: send-email - container: - image: alpine:latest - command: [sh, -c] - args: ["echo send e-mail: {{workflow.name}} {{workflow.status}}"] - - name: celebrate - container: - image: alpine:latest - command: [sh, -c] - args: ["echo hooray!"] - - name: cry - container: - image: alpine:latest - command: [sh, -c] - args: ["echo boohoo!"] -``` - - | -- -```yaml -id: exit-handlers- -name: Exit/Error Handling Example -version: '1.0.0' -specVersion: '0.8' -autoRetries: true -start: intentional-fail-state -functions: - - name: intentional-fail-function - metadata: - image: alpine:latest - command: "[sh, -c]" - - name: send-email-function - metadata: - image: alpine:latest - command: "[sh, -c]" - - name: celebrate-cry-function - metadata: - image: alpine:latest - command: "[sh, -c]" -errors: - - name: IntentionalError - code: '404' -states: - - name: intentional-fail-state - type: operation - actions: - - functionRef: - refName: intentional-fail-function - arguments: - args: echo intentional failure; exit 1 - nonRetryableErrors: - - IntentionalError - onErrors: - - errorRef: IntentionalError - transition: send-email-state - end: true - - name: send-email-state - type: operation - actions: - - functionRef: - refName: send-email-function - arguments: - args: 'echo send e-mail: ${ .workflow.name } ${ .workflow.status }' - transition: emo-state - - name: emo-state - type: switch - dataConditions: - - condition: ${ .workflow| .status == "Succeeded" } - transition: celebrate-state - - condition: ${ .workflow| .status != "Succeeded" } - transition: cry-state - - name: celebrate-state - type: operation - actions: - - functionRef: - refName: celebrate-cry-function - arguments: - args: echo hooray! - end: true - - name: cry-state - type: operation - actions: - - functionRef: - refName: celebrate-cry-function - arguments: - args: echo boohoo! - end: true -``` - - | -
BPMN2 Diagram | -Serverless Workflow | -
---|---|
-
- |
-- -```yaml -id: processfile -name: Process File Workflow -version: '1.0.0' -specVersion: '0.8' -start: Process File -states: -- name: Process File - type: operation - actions: - - functionRef: processFile - end: true -functions: -- name: processFile - operation: file://myservice.json#process -``` - - | -
BPMN2 Diagram | -Serverless Workflow | -
---|---|
-
- |
-- -```yaml -id: processapplication -name: Process Application -version: '1.0.0' -specVersion: '0.8' -start: ProcessNewApplication -states: -- name: ProcessNewApplication - type: event - onEvents: - - eventRefs: - - ApplicationReceivedEvent - actions: - - functionRef: processApplicationFunction - - functionRef: acceptApplicantFunction - - functionRef: depositFeesFunction - end: - produceEvents: - - eventRef: NotifyApplicantEvent -functions: -- name: processApplicationFunction - operation: file://myservice.json#process -- name: acceptApplicantFunction - operation: file://myservice.json#accept -- name: depositFeesFunction - operation: file://myservice.json#deposit -events: -- name: ApplicationReceivedEvent - type: application - source: "/applications/new" -- name: NotifyApplicantEvent - type: notifications - source: "/applicants/notify" -``` - - | -
BPMN2 Diagram | -Serverless Workflow | -
---|---|
-
- |
-- -```yaml -id: simplecompensation -name: Simple Compensation -version: '1.0.0' -specVersion: '0.8' -start: Step 1 -states: -- name: Step 1 - type: operation - actions: - - functionRef: step1function - compensatedBy: Cancel Step 1 - transition: Step 2 -- name: Step 2 - type: operation - actions: - - functionRef: step2function - transition: OK? -- name: OK? - type: switch - dataConditions: - - name: 'yes' - condition: ${ .outcome | .ok == "yes" } - end: true - - name: 'no' - condition: ${ .outcome | .ok == "no" } - end: - compensate: true -- name: Cancel Step 1 - type: operation - usedForCompensation: true - actions: - - functionRef: undostep1 -functions: -- name: step1function - operation: file://myservice.json#step1 -- name: step2function - operation: file://myservice.json#step2 -- name: undostep1function - operation: file://myservice.json#undostep1 -``` - - | -
BPMN2 Diagram | -Serverless Workflow | -
---|---|
-
- |
-- -```yaml ---- -id: errorwithretries -name: Error Handling With Retries Workflow -version: '1.0.0' -specVersion: '0.8' -start: Make Coffee -states: - - name: Make Coffee - type: operation - actions: - - functionRef: makeCoffee - transition: Add Milk - - name: Add Milk - type: operation - actions: - - functionRef: addMilk - retryRef: noMilkRetries - retryableErrors: - - D'oh! No more Milk! - onErrors: - - errorRef: D'oh! No more Milk! - end: true - transition: Drink Coffee - - name: Drink Coffee - type: operation - actions: - - functionRef: drinkCoffee - end: true -retries: - - name: noMilkRetries - delay: PT1M - maxAttempts: 10 -errors: - - name: D'oh! No more Milk! - code: '123' -functions: - - name: makeCoffee - operation: file://myservice.json#make - - name: addMilk - operation: file://myservice.json#add - - name: drinkCoffee - operation: file://myservice.json#drink - -``` - - | -
BPMN2 Diagram | -Serverless Workflow | -
---|---|
-
- |
-- -```yaml -id: executiontimeout -name: Execution Timeout Workflow -version: '1.0.0' -specVersion: '0.8' -start: Purchase Parts -timeouts: - workflowExecTimeout: - duration: PT7D - interrupt: true - runBefore: Handle timeout -states: -- name: Purchase Parts - type: operation - actions: - - functionRef: purchasePartsFunction - transition: Unpack Parts -- name: Unpack Parts - type: operation - actions: - - functionRef: unpackPartsFunction - end: true -- name: Handle timeout - type: operation - actions: - - functionRef: handleTimeoutFunction -functions: -- name: purchasePartsFunction - operation: file://myservice.json#purchase -- name: unpackPartsFunction - operation: file://myservice.json#unpack -- name: handleTimeoutFunction - operation: file://myservice.json#handle -``` - - | -
BPMN2 Diagram | -Serverless Workflow | -
---|---|
-
- |
-- -```yaml -id: foreachWorkflow -name: ForEach State Workflow -version: '1.0.0' -specVersion: '0.8' -start: ForEachItem -states: -- name: ForEachItem - type: foreach - inputCollection: "${ .inputsArray }" - iterationParam: "${ .inputItem }" - outputCollection: "${ .outputsArray }" - actions: - - subFlowRef: doSomethingAndWaitForMessage - end: true -``` - - | -
BPMN2 Diagram | -Serverless Workflow | -
---|---|
-
- |
-- -```yaml -id: subflowloop -name: SubFlow Loop Workflow -version: '1.0.0' -specVersion: '0.8' -start: SubflowRepeat -states: -- name: SubflowRepeat - type: operation - actions: - - functionRef: checkAndReplyToEmail - actionDataFilter: - fromStateData: ${ .someInput } - toStateData: ${ .someInput } - stateDataFilter: - output: ${ .maxChecks -= 1 } - transition: CheckCount -- name: CheckCount - type: switch - dataConditions: - - condition: ${ .maxChecks > 0 } - transition: SubflowRepeat - defaultCondition: - end: true -``` - - | -
BPMN2 Diagram | -Serverless Workflow | -
---|---|
-
- |
-- -```yaml -id: approvereport -name: Approve Report Workflow -version: '1.0.0' -specVersion: '0.8' -start: Approve Report -states: -- name: Approve Report - type: callback - action: - functionRef: managerDecideOnReport - eventRef: ReportDecisionMadeEvent - transition: Evaluate Report Decision -- name: Evaluate Report Decision - type: switch - dataConditions: - - name: Approve - condition: "${ .decision | .approved == true }" - end: true - - name: Reject - condition: "${ .decision | .approved != true }" - transition: Update Report -- name: Update Report - type: callback - action: - functionRef: workerUpdateReport - eventRef: ReportUpdatedEvent - transition: Approve Report -events: -- name: ReportDecisionMadeEvent - type: report.decisions - source: reports/decision -- name: ReportUpdatedEvent - type: report.updated - source: reports/updated -functions: -- name: managerDecideOnReport - operation: file://myservice.json#managerapproval -- name: workerUpdateReport - operation: file://myservice.json#workerupdate -``` - - | -
BPMN2 Diagram | -Serverless Workflow | -
---|---|
-
- |
-- -```yaml -id: eventdecision -name: Event Decision workflow -version: '1.0.0' -specVersion: '0.8' -start: A -states: -- name: A - type: operation - actions: - - subFlowRef: asubflowid - transition: Event Decision -- name: Event Decision - type: switch - eventConditions: - - eventRef: EventB - transition: B - - eventRef: EventC - transition: C -- name: B - type: operation - actions: - - name: doSomething - functionRef: doSomethingFunction - end: true -- name: C - type: operation - actions: - - name: doSomething - functionRef: doSomethingFunction - end: true -events: -- name: EventB - type: my.events.b - source: "/events/+" -- name: EventC - type: my.events.c - source: "/events/+" -functions: -- name: doSomethingFunction - operation: file://myservice.json#dosomething -``` - - | -
Brigade | -Serverless Workflow | -
---|---|
- -```javascript -const { events, Job } = require("brigadier"); - -events.on("exec", exec); - -function exec(e, p) { - let j1 = new Job("j1", "alpine:3.7", ["echo hello"]); - let j2 = new Job("j2", "alpine:3.7", ["echo goodbye"]); - - j1.run() - .then(() => { - return j2.run() - }) - .then(() => { - console.log("done"); - }); -}; -``` - - | -- -```yaml -id: greeting -name: Greeting Workflow -version: '1.0.0' -specVersion: '0.8' -start: GreetingState -events: -- name: execEvent - type: exec -functions: -- name: greetingFunction - metadata: - image: alpine:3.7 - command: echo -- name: consoleLogFunction - type: console -states: -- name: GreetingState - type: event - onEvents: - - eventRefs: - - execEvent - actions: - - name: sayHelloAction - functionRef: - refName: greetingFunction - arguments: - greeting: hello - - name: sayGoodbyeAction - functionRef: - refName: greetingFunction - arguments: - greeting: hello - - name: logDoneAction - functionRef: - refName: consoleLogFunction - arguments: - log: done - end: true -``` - - | -
Brigade | -Serverless Workflow | -
---|---|
- -```javascript -const { events, Job } = require("brigadier"); - -events.on("exec", exec); - -async function exec(e, p) { - let j1 = new Job("j1", "alpine:3.7", ["echo hello"]); - // This will fail - let j2 = new Job("j2", "alpine:3.7", ["exit 1"]); - - try { - await j1.run(); - await j2.run(); - console.log("done"); - } catch (e) { - console.log(`Caught Exception ${e}`); - } -}; -``` - - | -- -```yaml -id: greetingwitherrorcheck -name: Greeting Workflow With Error Check -version: '1.0.0' -specVersion: '0.8' -autoRetries: true -start: GreetingState -events: -- name: execEvent - type: exec -errors: -- name: CommonError - code: '123' -functions: -- name: greetingFunction - metadata: - image: alpine:3.7 - command: echo -- name: consoleLogFunction - metadata: - type: console -states: -- name: GreetingState - type: event - onEvents: - - eventRefs: - - execEvent - actions: - - name: sayHelloAction - functionRef: - refName: greetingFunction - arguments: - greeting: hello - nonRetryableErrors: - - CommonError - - name: sayGoodbyeAction - functionRef: - refName: greetingFunction - arguments: - greeting: hello - nonRetryableErrors: - - CommonError - - name: logDoneAction - functionRef: - refName: consoleLogFunction - arguments: - log: done - nonRetryableErrors: - - CommonError - onErrors: - - errorRef: CommonError - transition: HandleErrorState - end: true -- name: HandleErrorState - type: operation - actions: - - name: logErrorAction - functionRef: - refName: consoleLogFunction - arguments: - log: Caught Exception ${ .exception } - end: true -``` - - | -
Brigade | -Serverless Workflow | -
---|---|
- -```javascript -const { events } = require("brigadier") - -events.on("exec", () => { - console.log("==> handling an 'exec' event") -}) - -events.on("push", () => { - console.log(" **** I'm a GitHub 'push' handler") -}) -``` - - | -- -```yaml -id: multieventworkflow -name: Multiple Events Workflow -version: '1.0.0' -specVersion: '0.8' -start: GreetingState -events: -- name: execEvent - type: exec -- name: pushEvent - type: push -functions: -- name: consoleLogFunction - type: console -states: -- name: GreetingState - type: event - onEvents: - - eventRefs: - - execEvent - actions: - - name: logExecEventAction - functionRef: - refName: consoleLogFunction - arguments: - log: "==> handling an 'exec' event" - - eventRefs: - - pushEvent - actions: - - name: logPushEventAction - functionRef: - refName: consoleLogFunction - arguments: - log: "**** I'm a GitHub 'push' handler" - end: true -``` - - | -
Brigade | -Serverless Workflow | -
---|---|
- -```javascript -const { events, Job, Group } = require("brigadier") - -events.on("exec", () => { - var hello = new Job("hello", "alpine:3.4", ["echo hello"]) - var goodbye = new Job("goodbye", "alpine:3.4", ["echo goodbye"]) - - var helloAgain = new Job("hello-again", "alpine:3.4", ["echo hello again"]) - var goodbyeAgain = new Job("bye-again", "alpine:3.4", ["echo bye again"]) - - - var first = new Group() - first.add(hello) - first.add(goodbye) - - var second = new Group() - second.add(helloAgain) - second.add(goodbyeAgain) - - first.runAll().then( () => second.runAll() ) -}) -``` - - | -- -```yaml -id: groupActionsWorkflow -name: Group Actions Workflow -version: '1.0.0' -specVersion: '0.8' -start: FirstGreetGroup -events: -- name: execEvent - type: exec -functions: -- name: echoFunction - metadata: - image: alpine:3.7 - command: echo -states: -- name: FirstGreetGroup - type: event - onEvents: - - eventRefs: - - execEvent - actions: - - name: firstHelloAction - functionRef: - refName: echoFunction - arguments: - message: hello - - name: firstGoodbyeAction - functionRef: - refName: echoFunction - arguments: - message: goodbye - transition: SecondGreetGroup -- name: SecondGreetGroup - type: operation - actions: - - name: secondHelloAction - functionRef: - refName: echoFunction - arguments: - message: hello-again - - name: secondGoodbyeAction - functionRef: - refName: echoFunction - arguments: - message: bye-again - end: true -``` - - | -
Brigade | -Serverless Workflow | -
---|---|
- -```javascript -const { events } = require("brigadier") - -events.on("exec", (e, p) => { - console.log(">>> event " + e.type + " caused by " + e.provider) - console.log(">>> project " + p.name + " clones the repo at " + p.repo.cloneURL) -}) -``` - - | -- -```yaml -id: eventDataWorkflow -name: Event Data Workflow -version: '1.0.0' -specVersion: '0.8' -start: LogEventData -events: -- name: execEvent - type: exec - dataOnly: false -functions: -- name: consoleFunction - type: console -states: -- name: LogEventData - type: event - onEvents: - - eventRefs: - - execEvent - eventDataFilter: - toStateData: "${ .event }" - actions: - - name: eventInfoAction - functionRef: - refName: consoleFunction - arguments: - log: ">>> event ${ .event.type } caused by ${ .event.data.provider }" - - name: projectInfoAction - functionRef: - refName: consoleFunction - arguments: - log: ">>> project ${ .event.data.project.name } clones the repo at by ${ .event.data.repo.cloneURL }" - end: true - -``` - - | -
Brigade | -Serverless Workflow | -
---|---|
- -```javascript -const { events, Job, Group } = require("brigadier") - -events.on("exec", (e, p) => { - var dest = "/mnt/brigade/share/hello.txt" - var one = new Job("one", "alpine:3.4", ["echo hello > " + dest]) - var two = new Job("two", "alpine:3.4", ["echo world >> " + dest]) - var three = new Job("three", "alpine:3.4", ["cat " + dest]) - - one.storage.enabled = true - two.storage.enabled = true - three.storage.enabled = true - - Group.runEach([one, two, three]) -}) -``` - - | -- -```yaml -id: actionResultsWorkflow -name: Action Results Workflow -version: '1.0.0' -specVersion: '0.8' -start: ExecActionsAndStoreResults -events: -- name: execEvent - type: exec -functions: -- name: greetingFunction - metadata: - image: alpine:3.7 - command: echo -- name: storeToFileFunction - metadata: - image: alpine:3.7 - command: filestore -states: -- name: ExecActionsAndStoreResults - type: event - onEvents: - - eventRefs: - - execEvent - eventDataFilter: - toStateData: "${ .event }" - actions: - - name: helloAction - actionDataFilter: - results: "${ .helloResult }" - functionRef: - refName: greetingFunction - arguments: - message: hello - - name: worldAction - actionDataFilter: - results: "${ .worldResults }" - functionRef: - refName: greetingAction - arguments: - message: world - - name: storeToFileAction - functionRef: - refName: storeToFileFunction - arguments: - destination: "${ .event.destination }" - value: "${ .helloResult } ${ .worldResults }" - end: true - -``` - - | -
Brigade | -Serverless Workflow | -
---|---|
- -```javascript -const {events} = require("brigadier") - -events.on("exec", function(e, project) { - const e2 = { - type: "next", - provider: "exec-handler", - buildID: e.buildID, - workerID: e.workerID, - cause: {event: e} - } - events.fire(e2, project) -}) - -events.on("next", (e) => { - console.log(`fired ${e.type} caused by ${e.cause.event.type}`) -}) -``` - - | -- -```yaml -id: eventDataWorkflow -name: Event Data Workflow -version: '1.0.0' -specVersion: '0.8' -start: ExecEventState -events: -- name: execEvent - type: exec - dataOnly: false -- name: nextEvent - type: next - kind: produced -functions: -- name: consoleLogFunction - type: console -states: -- name: ExecEventState - type: event - onEvents: - - eventRefs: - - execEvent - actions: [] - eventDataFilter: - toStateData: "${ .execEvent }" - transition: - nextState: NextEventState - produceEvents: - - eventRef: nextEvent - data: - type: next - provider: exec-handler - buildID: "${ .execEvent.data.buildID }" - workerID: "${ .execEvent.data.workerID }" - cause: - event: "${ .execEvent }" -- name: NextEventState - type: event - onEvents: - - eventRefs: - - nextEvent - eventDataFilter: - toStateData: "${ .nextEvent }" - actions: - - name: consoleLogAction - functionRef: - refName: consoleLogFunction - arguments: - log: "fired ${ .nextEvent.data.type } caused by ${ .nextEvent.data.cause.event }" - end: true -``` - - | -
Serverless Workflow | -|
---|---|
- -```json -{ - "main": { - "params": [ - "args" - ], - "steps": [ - { - "step1": { - "assign": [ - { - "outputVar": "${\"Hello \" + args.firstName + \" \" + args.lastName}" - } - ] - } - }, - { - "step2": { - "return": "${outputVar}" - } - } - ] - } -} -``` - - | -- -```json -{ - "id": "greetingwithargs", - "name": "Greeting With Args", - "specVersion": "0.8", - "start": "Set Output", - "states": [ - { - "name": "Set Output", - "type": "inject", - "data": { - "outputVar": "Hello ${ .firstname + \" \" + .lastname }" - }, - "stateDataFilter": { - "output": "${ .outputVar }" - }, - "end": true - } - ] -} -``` - - | -
Serverless Workflow | -|
---|---|
- -```json -[ - { - "define": { - "assign": [ - { - "array": [ - "foo", - "ba", - "r" - ] - }, - { - "result": "" - }, - { - "i": 0 - } - ] - } - }, - { - "check_condition": { - "switch": [ - { - "condition": "${len(array) > i}", - "next": "iterate" - } - ], - "next": "exit_loop" - } - }, - { - "iterate": { - "assign": [ - { - "result": "${result + array[i]}" - }, - { - "i": "${i+1}" - } - ], - "next": "check_condition" - } - }, - { - "exit_loop": { - "return": { - "concat_result": "${result}" - } - } - } -] -``` - - | -- -```json -{ - "id": "concatarray", - "name": "Concatenating array values", - "start": "DoConcat", - "specVersion": "0.8", - "states": [ - { - "name": "DoConcat", - "type": "inject", - "data": { - "array": [ - "foo", - "ba", - "r" - ] - }, - "stateDataFilter": { - "output": "${ .array | join(\"\") }" - }, - "end": true - } - ] -} -``` - - | -
Serverless Workflow | -|
---|---|
- -```json -[ - { - "initialize": { - "assign": [ - { - "project": "${sys.get_env(\"GOOGLE_CLOUD_PROJECT_NUMBER\")}" - }, - { - "zone": "us-central1-a" - }, - { - "vmToStop": "examplevm" - } - ] - } - }, - { - "stopInstance": { - "call": "http.post", - "args": { - "url": "${\"https://compute.googleapis.com/compute/v1/projects/\"+project+\"/zones/\"+zone+\"/instances/\"+vmToStop+\"/stop\"}", - "auth": { - "type": "OAuth2" - } - }, - "result": "stopResult" - } - } -] -``` - - | -- -```json -{ - "id": "stopcomputeengine", - "name": "Stop Compute Engine", - "specVersion": "0.8", - "start": "DoStop", - "states": [ - { - "name": "DoStop", - "type": "operation", - "actions": [ - { - "functionRef": { - "refName": "StopComputeEngine", - "arguments": { - "project": "${ .project }", - "zone": "${ .zone }", - "vmToStop": "${ .vmToStop }" - } - } - } - ], - "end": true - } - ], - "functions": [ - { - "name": "StopComputeEngine", - "operation": "computeengineopenapi.json#stopengine" - } - ] -} -``` - - | -
Serverless Workflow | -|
---|---|
- -```json -[ - { - "initVariables": { - "assign": [ - { - "project": "${sys.get_env(\"GOOGLE_CLOUD_PROJECT_ID\")}" - }, - { - "topic": "mytopic1" - }, - { - "message": "Hello world!" - } - ] - } - }, - { - "publish": { - "try": { - "call": "googleapis.pubsub.v1.projects.topics.publish", - "args": { - "topic": "${\"projects/\" + project + \"/topics/\" + topic}", - "body": { - "messages": [ - { - "data": "${base64.encode(text.encode(message))}" - } - ] - } - }, - "result": "publishResult" - }, - "except": { - "as": "e", - "steps": [ - { - "handlePubSubError": { - "switch": [ - { - "condition": "${e.code == 404}", - "raise": "PubSub Topic not found" - }, - { - "condition": "${e.code == 403}", - "raise": "Error authenticating to PubSub" - } - ] - } - }, - { - "unhandledException": { - "raise": "${e}" - } - } - ] - } - } - }, - { - "last": { - "return": "${publishResult}" - } - } -] -``` - - | -- -```json -{ - "id": "publishtotopicwitherrorhandling", - "name": "Publish To Topic With Error Handling", - "specVersion": "0.8", - "start": "DoPublish", - "errors": [ - { - "name": "PubSub Topic not found", - "code": "404" - }, - { - "name": "Error authenticating to PubSub", - "code": "403" - } - ], - "states": [ - { - "name": "DoPublish", - "type": "operation", - "actions": [ - { - "functionRef": { - "refName": "PublishToTopic", - "arguments": { - "project": "${ .project }", - "topic": "${ .topic }", - "message": "${ .message }" - } - } - } - ], - "onErrors": [ - { - "errorRef": "PubSub Topic not found", - "end": { - "produceEvents": [ - { - "eventRef": "TopicError", - "data": { "message": "PubSub Topic not found"} - } - ] - } - }, - { - "errorRef": "Error authenticating to PubSub", - "end": { - "produceEvents": [ - { - "eventRef": "TopicError", - "data": { "message": "Error authenticating to PubSub"} - } - ] - } - } - ], - "end": true - } - ], - "functions": [ - { - "name": "PublishToTopic", - "operation": "pubsubapi.json#publish" - } - ], - "events": [ - { - "name": "TopicError", - "source": "pubsub.topic.events", - "type": "pubsub/events" - } - ] -} -``` - - | -
Serverless Workflow | -|
---|---|
- -```json -{ - "main": { - "steps": [ - { - "read_item": { - "try": { - "call": "http.get", - "args": { - "url": "https://host.com/api" - }, - "result": "api_response" - }, - "retry": { - "predicate": "${custom_predicate}", - "max_retries": 5, - "backoff": { - "initial_delay": 2, - "max_delay": 60, - "multiplier": 2 - } - } - } - }, - { - "last_step": { - "return": "OK" - } - } - ] - }, - "custom_predicate": { - "params": [ - "e" - ], - "steps": [ - { - "what_to_repeat": { - "switch": [ - { - "condition": "${e.code == 500}", - "return": true - } - ] - } - }, - { - "otherwise": { - "return": false - } - } - ] - } -} -``` - - | -- -```json -{ - "id": "errorhandlingwithretries", - "name": "Error Handling with Retries", - "start": "ReadItem", - "specVersion": "0.8", - "states": [ - { - "name": "ReadItem", - "type": "operation", - "actions": [ - { - "functionRef": "ReadItemFromApi", - "retryRef": "ServiceNotAvailableRetryPolicy", - "retryableErrors": ["Service Not Available"] - } - ], - "onErrors": [ - { - "errorRef": "Service Not Available", - "end": true - } - ], - "end": true - } - ], - "functions": [ - { - "name": "ReadItemFromApi", - "operation": "someapi.json#read" - } - ], - "errors": [ - { - "name": "Service Not Available", - "code": "500" - } - ], - "retries": [ - { - "name": "ServiceNotAvailableRetryPolicy", - "maxAttempts": 5, - "delay": "PT2S", - "maxDelay": "PT60S", - "multiplier": 2 - } - ] -} -``` - - | -
Serverless Workflow | -|
---|---|
- -```json -{ - "main": { - "steps": [ - { - "first": { - "call": "hello", - "args": { - "input": "Kristof" - }, - "result": "someOutput" - } - }, - { - "second": { - "return": "${someOutput}" - } - } - ] - }, - "hello": { - "params": [ - "input" - ], - "steps": [ - { - "first": { - "return": "${\"Hello \"+input}" - } - } - ] - } -} -``` - - | -- -```json -{ - "id": "callsubflow", - "name": "Call SubFlow", - "start": "CallSub", - "states": [ - { - "name": "CallSub", - "type":"operation", - "actions": [ - { - "subFlowRef": "calledsubflow" - } - ], - "end": true - } - ] -} -``` - - | -
Serverless Workflow | -|
---|---|
- -```json -[ - { - "firstStep": { - "call": "http.get", - "args": { - "url": "https://www.example.com/callA" - }, - "result": "firstResult" - } - }, - { - "whereToJump": { - "switch": [ - { - "condition": "${firstResult.body.SomeField < 10}", - "next": "small" - }, - { - "condition": "${firstResult.body.SomeField < 100}", - "next": "medium" - } - ], - "next": "large" - } - }, - { - "small": { - "call": "http.get", - "args": { - "url": "https://www.example.com/SmallFunc" - }, - "next": "end" - } - }, - { - "medium": { - "call": "http.get", - "args": { - "url": "https://www.example.com/MediumFunc" - }, - "next": "end" - } - }, - { - "large": { - "call": "http.get", - "args": { - "url": "https://www.example.com/LargeFunc" - }, - "next": "end" - } - } -] -``` - - | -- -```json -{ - "id": "databasedconditions", - "name": "Data Based Conditions", - "start": "CallA", - "states": [ - { - "name": "CallA", - "type":"operation", - "actions": [ - { - "functionRef": "callFunctionA" - } - ], - "transition": "EvaluateAResults" - }, - { - "name": "EvaluateAResults", - "type": "switch", - "dataConditions": [ - { - "name": "Less than 10", - "condition": "${ .body | .SomeField < 10 }", - "transition": "CallSmall" - }, - { - "name": "Less than 100", - "condition": "${ .body | .SomeField < 100 }", - "transition": "CallMedium" - } - ], - "defaultCondition": { - "transition": "CallLarge" - } - }, - { - "name": "CallSmall", - "type":"operation", - "actions": [ - { - "functionRef": "callFunctionSmall" - } - ], - "end": true - }, - { - "name": "CallMedium", - "type":"operation", - "actions": [ - { - "functionRef": "callFunctionMedium" - } - ], - "end": true - }, - { - "name": "CallLarge", - "type":"operation", - "actions": [ - { - "functionRef": "callFunctionMedium" - } - ], - "end": true - } - ], - "functions": [ - { - "name": "callFunctionA", - "operation": "myapi.json#calla" - }, - { - "name": "callFunctionSmall", - "operation": "myapi.json#callsmall" - }, - { - "name": "callFunctionMedium", - "operation": "myapi.json#callmedium" - }, - { - "name": "callFunctionLarge", - "operation": "myapi.json#calllarge" - } - ] -} -``` - - | -
Temporal | -Serverless Workflow | -
---|---|
- -```java -// Workflow implementation -public static class GreetingWorkflowImpl implements GreetingWorkflow { - private final GreetingActivities activities = - Workflow.newActivityStub( - GreetingActivities.class, - ActivityOptions.newBuilder().setScheduleToCloseTimeout(Duration.ofSeconds(2)).build()); - - // Workflow method - @Override - public String getGreeting(String name) { - return activities.composeGreeting("Hello", name); - } -} -``` - - | -- -```json -{ - "id": "greetingworkflow", - "name": "Greeting Workflow", - "version": "1.0.0", - "specVersion": "0.8", - "autoRetries": true, - "states": [ - { - "name": "Greet", - "type": "operation", - "actions": [ - { - "name": "Greet Action", - "functionRef": { - "refName": "GreetingFunction", - "arguments": { - "prefix": "Hello", - "name": "${ .name }" - } - } - } - ], - "timeouts": { - "actionExecTimeout": "PT2S" - }, - "end": true - } - ], - "functions": [ - { - "name": "GreetingFunction", - "operation": "myactionsapi.json#composeGreeting" - } - ] -} -``` - - | -
Temporal | -Serverless Workflow | -
---|---|
- -```java -// Workflow implementation -public static class GreetingWorkflowImpl implements GreetingWorkflow { - private final GreetingActivities activities = - Workflow.newActivityStub( - GreetingActivities.class, - ActivityOptions.newBuilder().setScheduleToCloseTimeout(Duration.ofSeconds(10)).build()); - - @Override - public String greet(String name) { - activities.greet("Hello " + name + "!"); - } -} - -// Client code Workflow Options (cron) -WorkflowOptions workflowOptions = - WorkflowOptions.newBuilder() - .setWorkflowId(CRON_WORKFLOW_ID) - .setTaskQueue(TASK_QUEUE) - .setCronSchedule("* * * * *") - .setWorkflowExecutionTimeout(Duration.ofMinutes(10)) - .build(); - -``` - - | -- -```json -{ - "id": "greetingworkflow", - "name": "Greeting Workflow", - "version": "1.0.0", - "specVersion": "0.8", - "autoRetries": true, - "timeouts": { - "workflowExecTimeout": "PT10M" - } - "start": { - "stateName": "GreetingState", - "schedule": { - "cron": { - "expression": "* * * * *" - } - } - }, - "states": [ - { - "name": "GreetingState", - "type": "operation", - "actions": [ - { - "name": "Greet", - "functionRef": { - "refName": "GreetingFunction", - "arguments": { - "prefix": "Hello", - "name": "${ .name }" - } - } - } - ], - "timeouts": { - "actionExecTimeout": "PT2S" - }, - "end": true - } - ], - "functions": [ - { - "name": "GreetingFunction", - "operation": "myactionsapi.json#greet" - } - ] -} -``` - - | -
Temporal | -Serverless Workflow | -
---|---|
-
-```java
-// Workflow implementation
- public static class SagaWorkflowImpl implements SagaWorkflow {
- ActivityOperation activity =
- Workflow.newActivityStub(
- ActivityOperation.class,
- ActivityOptions.newBuilder().setScheduleToCloseTimeout(Duration.ofSeconds(2)).build());
-
- // Workflow Method
- @Override
- public void execute() {
- Saga saga = new Saga(new Saga.Options.Builder().setParallelCompensation(false).build());
- try {
- // The following demonstrate how to compensate sync invocations.
- ChildWorkflowOperation op1 = Workflow.newChildWorkflowStub(ChildWorkflowOperation.class);
- op1.execute(10);
- ChildWorkflowCompensation c1 =
- Workflow.newChildWorkflowStub(ChildWorkflowCompensation.class);
- saga.addCompensation(c1::compensate, -10);
-
- // The following demonstrate how to compensate async invocations.
- Promise |
-- -```json -{ - "id": "HelloSaga", - "name": "Hello SAGA compensation Workflow", - "version": "1.0.0", - "specVersion": "0.8", - "states": [ - { - "name": "ExecuteState", - "type": "operation", - "compensatedBy": "CompensateState", - "actions": [ - { - "name": "Execute", - "functionRef": { - "refName": "ExecuteFunction", - "arguments": { - "amount": 10 - } - } - } - ], - "end": { - "compensate": true - } - }, - { - "name": "CompensateState", - "type": "operation", - "usedForCompensation": true, - "actions": [ - { - "name": "Compensate", - "functionRef": { - "refName": "CompensateFunction", - "arguments": { - "amount": -10 - } - } - } - ] - } - ], - "functions": [ - { - "name": "ExecuteFunction", - "operation": "myactionsapi.json#execute" - }, - { - "name": "CompensateFunction", - "operation": "myactionsapi.json#compensate" - } - ] -} -``` - - | -
Temporal | -Serverless Workflow | -
---|---|
- -```java -// Workflow Implementation -public static class GreetingWorkflowImpl implements GreetingWorkflow { - private final GreetingActivities activities = - Workflow.newActivityStub( - GreetingActivities.class, - ActivityOptions.newBuilder() - .setScheduleToCloseTimeout(Duration.ofSeconds(10)) - .setRetryOptions( - RetryOptions.newBuilder() - .setInitialInterval(Duration.ofSeconds(1)) - .setDoNotRetry(IllegalArgumentException.class.getName()) - .build()) - .build()); - @Override - public String getGreeting(String name) { - // This is a blocking call that returns only after activity is completed. - return activities.composeGreeting("Hello", name); - } -} - -// Activity Implementation -static class GreetingActivitiesImpl implements GreetingActivities { - private int callCount; - private long lastInvocationTime; - - @Override - public synchronized String composeGreeting(String greeting, String name) { - if (lastInvocationTime != 0) { - long timeSinceLastInvocation = System.currentTimeMillis() - lastInvocationTime; - System.out.print(timeSinceLastInvocation + " milliseconds since last invocation. "); - } - lastInvocationTime = System.currentTimeMillis(); - if (++callCount < 4) { - System.out.println("composeGreeting activity is going to fail"); - throw new IllegalStateException("not yet"); - } - System.out.println("composeGreeting activity is going to complete"); - return greeting + " " + name + "!"; - } -} -``` - - | -- -```json -{ - "id": "HelloActivityRetry", - "name": "Hello Activity with Retries Workflow", - "version": "1.0.0", - "specVersion": "0.8", - "autoRetries": true, - "start": "GreetingState", - "states": [ - { - "name": "GreetingState", - "type": "operation", - "actions": [ - { - "name": "Greet", - "functionRef": { - "refName": "GreetingFunction", - "arguments": { - "name": "World" - }, - "retryRef": "GreetingRetry", - "nonRetryableErrors": ["IllegalArgumentException"] - } - } - ], - "timeouts": { - "actionExecTimeout": "PT10S" - }, - "onErrors": [ - { - "errorRefs": ["IllegalStateException", "IllegalArgumentException"], - "end": true - } - ], - "end": true - } - ], - "functions": [ - { - "name": "GreetingFunction", - "operation": "myactionsapi.json#composeGreeting" - } - ], - "errors": [ - { - "name": "IllegalStateException" - }, - { - "name": "IllegalArgumentException" - } - ], - "retries": [ - { - "name": "GreetingRetry", - "delay": "PT1S" - } - ] -} -``` - - | -
`io.serverlessworkflow.workflow.started.v1`| [`workflowStartedEvent`](https://github.com/serverlessworkflow/specification/blob/main/dsl-reference.md#workflow-started-event) | `yes` | Notifies about the start of a workflow. | +|
`io.serverlessworkflow.workflow.suspended.v1`| [`workflowSupsendedEvent`](https://github.com/serverlessworkflow/specification/blob/main/dsl-reference.md#workflow-suspended-event) | `yes` | Notifies about suspending a workflow execution. | +|
`io.serverlessworkflow.workflow.resumed.v1`| [`workflowResumedEvent`](https://github.com/serverlessworkflow/specification/blob/main/dsl-reference.md#workflow-resumed-event) | `yes` | Notifies about resuming a workflow execution. | +|
`io.serverlessworkflow.workflow.correlation-started.v1`| [`workflowCorrelationStartedEvent`](https://github.com/serverlessworkflow/specification/blob/main/dsl-reference.md#workflow-correlation-started-event) | `yes` | Notifies about a workflow starting to correlate events. | +|
`io.serverlessworkflow.workflow.correlation-completed.v1`| [`workflowCorrelationCompletedEvent`](https://github.com/serverlessworkflow/specification/blob/main/dsl-reference.md#workflow-correlation-completed-event) | `yes` | Notifies about a workflow completing an event correlation. | +|
`io.serverlessworkflow.workflow.cancelled.v1`| [`workflowCancelledEvent`](https://github.com/serverlessworkflow/specification/blob/main/dsl-reference.md#workflow-cancelled-event) | `yes` | Notifies about the cancellation of a workflow execution. | +|
`io.serverlessworkflow.workflow.faulted.v1`| [`workflowFaultedEvent`](https://github.com/serverlessworkflow/specification/blob/main/dsl-reference.md#workflow-faulted-event) | `yes` | Notifies about a workflow being faulted. | +|
`io.serverlessworkflow.workflow.completed.v1`| [`workflowCompletedEvent`](https://github.com/serverlessworkflow/specification/blob/main/dsl-reference.md#workflow-completed-event) | `yes` |Notifies about the completion of a workflow execution. | +|
`io.serverlessworkflow.workflow.status-changed.v1`| [`workflowStatusChangedEvent`](https://github.com/serverlessworkflow/specification/blob/main/dsl-reference.md#workflow-status-changed-event) | `no` |Notifies about the change of a workflow's status phase. | + +> [!NOTE] +> The `io.serverlessworkflow.workflow.status-changed.v1` event is an optional convenience event that notifies consumers solely about a workflowās status changes, without carrying extra data. It is typically used by consumers who only need to track or report status updates (and not details like faults or outputs). Its use is optional because it requires runtimes to publish an additional event for each necessary lifecycle change. + +##### Task Lifecycle Events + +| Type | Data | Required | Description | +|:----:|:----:|:--------:|:------------| +|
`io.serverlessworkflow.task.created.v1`| [`taskCreatedEvent`](https://github.com/serverlessworkflow/specification/blob/main/dsl-reference.md#task-created-event) | `yes` | Notifies about the creation of a task. | +|
`io.serverlessworkflow.task.started.v1`| [`taskStartedEvent`](https://github.com/serverlessworkflow/specification/blob/main/dsl-reference.md#task-started-event) | `yes` | Notifies about the start of a task. | +|
`io.serverlessworkflow.task.suspended.v1`| [`taskSuspendedEvent`](https://github.com/serverlessworkflow/specification/blob/main/dsl-reference.md#task-suspended-event) | `yes` | Notifies about suspending a task's execution. | +|
`io.serverlessworkflow.task.resumed.v1`| [`taskResumedEvent`](https://github.com/serverlessworkflow/specification/blob/main/dsl-reference.md#task-resumed-event) | `yes` | Notifies about resuming a task's execution. | +|
`io.serverlessworkflow.task.retried.v1`| [`taskRetriedEvent`](https://github.com/serverlessworkflow/specification/blob/main/dsl-reference.md#task-retried-event) | `yes` | Notifies about retrying a task's execution. | +|
`io.serverlessworkflow.task.cancelled.v1`| [`taskCancelledEvent`](https://github.com/serverlessworkflow/specification/blob/main/dsl-reference.md#task-cancelled-event) | `yes` | Notifies about the cancellation of a task's execution. | +|
`io.serverlessworkflow.task.faulted.v1`| [`taskFaultedEvent`](https://github.com/serverlessworkflow/specification/blob/main/dsl-reference.md#task-faulted-event) | `yes` | Notifies about a task being faulted. | +|
`io.serverlessworkflow.task.completed.v1`| [`taskCompletedEvent`](https://github.com/serverlessworkflow/specification/blob/main/dsl-reference.md#task-completed-event) | `yes` | Notifies about the completion of a task's execution. | +|
`io.serverlessworkflow.task.status-changed.v1`| [`taskStatusChangedEvent`](https://github.com/serverlessworkflow/specification/blob/main/dsl-reference.md#task-status-changed-event) | `no` | Notifies about the change of a task's status phase. | + +> [!NOTE] +> The `io.serverlessworkflow.task.status-changed.v1` event is an optional convenience event that notifies consumers solely about a task's status changes, without carrying extra data. It is typically used by consumers who only need to track or report status updates (and not details like faults or outputs). Its use is optional because it requires runtimes to publish an additional event for each necessary lifecycle change. + +#### Components + +Serverless Workflow DSL allows for defining reusable components that can be referenced across the workflow. These include: + +- [Authentications](dsl-reference.md#authentication) +- [Errors](dsl-reference.md#error) +- [Extensions](dsl-reference.md#extension) +- [Functions](dsl-reference.md#task) +- [Retries](dsl-reference.md#retry) +- [Secrets](#secret) + +##### Task + +[Tasks](dsl-reference.md#tasks) are the fundamental computing units of a workflow. They define the different types of actions that a workflow can perform, including the ability to mutate their input and output data. Tasks can also write to and modify the context data, enabling complex and dynamic workflow behaviors. + +The Serverless Workflow DSL defines several default [task](dsl-reference.md#tasks) types that runtimes **must** implement: + +- [Call](dsl-reference.md#call), used to call services and/or functions. +- [Do](dsl-reference.md#do), used to define one or more subtasks to perform in sequence. +- [Emit](dsl-reference.md#emit), used to emit [events](dsl-reference.md#event). +- [For](dsl-reference.md#for), used to iterate over a collection of items, and conditionally perform a task for each of them. +- [Fork](dsl-reference.md#fork), used to define one or more two subtasks to perform in parallel. +- [Listen](dsl-reference.md#listen), used to listen for an [event](dsl-reference.md#event) or more. +- [Raise](dsl-reference.md#raise), used to raise an [error](dsl-reference.md#error) and potentially fault the [workflow](dsl-reference.md#workflow). +- [Run](dsl-reference.md#run), used to run a [container](dsl-reference.md#container-process), a [script](dsl-reference.md#script-process), a [shell](dsl-reference.md#shell-process) command or even another [workflow](dsl-reference.md#workflow-process). +- [Set](dsl-reference.md#set), used to dynamically set the [workflow](dsl-reference.md#workflow)'s data during the its execution. +- [Switch](dsl-reference.md#switch), used to dynamically select and execute one of multiple alternative paths based on specified conditions +- [Try](dsl-reference.md#try), used to attempt executing a specified [task](dsl-reference.md#task), and to handle any resulting [errors](dsl-reference.md#error) gracefully, allowing the [workflow](dsl-reference.md#workflow) to continue without interruption. +- [Wait](dsl-reference.md#wait), used to pause or wait for a specified duration before proceeding to the next task. + +To ensure they conform to the DSL, runtimes **should** pass all the feature conformance test scenarios defined in the [ctk](ctk/README.md). + +##### Secret + +Secrets are sensitive information required by a workflow to securely access protected resources or services. They provide a way to securely store and manage credentials, tokens, or other sensitive data used during workflow execution. + +Runtime **must** implement a mechanism capable of providing the workflow with the data contained within the defined secrets. If a workflow attempts to access a secret to which it does not have access rights or which does not exist, runtimes **must** raise an error with type `https://serverlessworkflow.io/spec/1.0.0/errors/authorization` and status `403`. + +#### Scheduling + +Workflow scheduling in ServerlessWorkflow allows developers to specify when and how their workflows should be executed, ensuring timely response to events and efficient resource utilization. It offers four key properties: `every`, `cron`, `after`, and `on`. + +- The `every` property defines the interval for workflow execution, ensuring periodic runs regardless of the previous run's status. +- With `cron`, developers can use CRON expressions to schedule workflow execution at specific times or intervals. +- `after` specifies a delay duration before restarting the workflow after completion. +- `on` enables event-driven scheduling, triggering workflow execution based on specified events. + +See the [DSL reference](dsl-reference.md#schedule) for more details about workflow scheduling. + +##### Event-driven scheduling + +###### Input of event-driven scheduled workflows + +In event-driven scheduled workflows, the input is structured as an array containing the events that trigger the execution of the workflow. This array serves as a vital resource, providing workflow authors access to all relevant data associated with each triggering event. When an event activates the workflow, it populates this array with one or more occurrences, allowing authors to process multiple events simultaneously as needed. + +Authors can reference individual events within the array using syntax such as $workflow.input[index], where index indicates the event's position, starting from 0. For instance, $workflow.input[0] refers to the first event, while $workflow.input[1] refers to the second. This structure allows for easy access to specific event details, and if multiple events are received at once, authors can iterate through the array to handle each one appropriately. This flexibility ensures that workflows can respond effectively to various conditions and triggers, enhancing their overall responsiveness and functionality. + +###### Distinguishing event-driven scheduling from start `listen` Tasks + +While both `schedule.on` and a start listener task enable event-driven execution of workflows, they serve distinct purposes and have different implications: + +- **`schedule.on`**: This property defines when a new workflow instance should be created based on an external event. When an event matches the criteria specified in `schedule.on`, a new workflow instance is initiated. The critical point here is that `schedule.on` solely manages the creation of new workflow instances. Any faults or timeouts related to the scheduling process are typically invisible to the user and do not impact the workflow instance. + +- **Start `listen` task**: A start listener task defines a task that must be undertaken after a new workflow instance has been created. This task listens for specific events and begins processing once the instance is active. The critical difference is that a start listener task operates within an already instantiated workflow. If a start listener task experiences a timeout or fault, it can cause the entire workflow instance to fail or behave unexpectedly, directly impacting the flow's execution and outcome. + +While `schedule.on` is concerned with *when* a new workflow instance should be initiated, a start listener task deals with *what* should happen once the instance is active. This distinction is crucial because it influences how errors and timeouts are handledā`schedule.on` faults are typically invisible and do not affect the workflow, whereas start listener task failures can directly and potentially severely impact the workflow instance they belong to. + +### Task Flow + +A workflow begins with the first task defined. + +Once the task has been executed, different things can happen: + +- `continue`: the task ran to completion, and the next task, if any, should be executed. The task to run next is implicitly the next in declaration order, or explicitly defined by the `then` property of the executed task. If the executed task is the last task, then the workflow's execution gracefully ends. +- `fault`: the task raised an uncaught error, which abruptly halts the workflow's execution and makes it transition to `faulted` [status phase](#status-phases). +- `end`: the task explicitly and gracefully ends the workflow's execution. + +> [!WARNING] +> Flow directives may only redirect to tasks declared within their own scope. In other words, they cannot target tasks at a different depth. + +### Data Flow + +In Serverless Workflow DSL, data flow management is crucial to ensure that the right data is passed between tasks and to the workflow itself. + +Here's how data flows through a workflow based on various transformation stages: + +1. **Validate Workflow Input** +Before the workflow starts, the input data provided to the workflow can be validated against the `input.schema` property to ensure it conforms to the expected structure. +The execution only proceeds if the input is valid. Otherwise, it will fault with a [ValidationError (https://serverlessworkflow.io/spec/1.0.0/errors/validation)](dsl-reference.md#error). + +2. **Transform Workflow Input** +Before the workflow starts, the input data provided to the workflow can be transformed to ensure only relevant data in the expected format is passed into the workflow context. This can be done using the top level `input.from` expression. It evaluates on the raw workflow input and defaults to the identity expression which leaves the input unchanged. This step allows the workflow to start with a clean and focused dataset, reducing potential overhead and complexity in subsequent tasks. The result of this expression will set as the initial value for the `$context` runtime expression argument and be passed to the first task. + +*Example: If the workflow receives a JSON object as input, a transformation can be applied to remove unnecessary fields and retain only those that are required for the workflow's execution.* + +After workflow input validation and transformation, the transformed input is passed as the raw input to the first task. + +3. **Validate Task Input** +Before a task executes, its raw input can be validated against the `input.schema` property to ensure it conforms to the expected structure. +The execution only proceeds if the input is valid. Otherwise, it will fault with a [ValidationError (https://serverlessworkflow.io/spec/1.0.0/errors/validation)](dsl-reference.md#error). + +4. **Transform Task Input** +The input data for the task can be transformed to match the specific requirements of that task. This ensures that the task receives only the data required to perform its operations. This can be done using the task's `input.from` expression. It evaluates the raw task input (i.e., the transformed workflow input for the first task or the transformed output of the previous task) and defaults to the identity expression, which leaves the input unchanged. The result of this expression will be set as the `$input` runtime expression argument and be passed to the task. This transformed input will be evaluated against any runtime expressions used within the task definition. + +*Example: If the task is a function call that only needs a subset of the workflow input, a transformation can be applied to provide only those fields needed for the function to execute.* + +5. **Transform Task Output** +After completing the task, its output can be transformed before passing it to the next task or storing it in the workflow context. Transformations are applied using the `output.as` runtime expression. It evaluates the raw task output and defaults to the identity expression, which leaves the output unchanged. Its result will be input for the next task. + +*Example: If the task returns a large dataset, a transformation can be applied to retain only the relevant results needed for subsequent tasks.* + +6. **Validate Task Output** +After `output.as` is evaluated, the transformed task output is validated against the `output.schema` property to ensure it conforms to the expected structure. The execution only proceeds if the output is valid. Otherwise, it will fault with a [ValidationError (https://serverlessworkflow.io/spec/1.0.0/errors/validation)](dsl-reference.md#error). + +7. **Update Workflow Context** +To update the context, one uses the `export.as` runtime expression. It evaluates the transformed task output and defaults to the expression that returns the existing context. The result of this runtime expression replaces the workflow's current context and the content of the `$context` runtime expression argument. This helps manage the data flow and keep the context clean by removing any unnecessary data produced by the task. + +8. **Validate Exported Context** +After the context is updated, the exported context is validated against the `export.schema` property to ensure it conforms to the expected structure. The execution only proceeds if the exported context is valid. Otherwise, it will fault with a [ValidationError (https://serverlessworkflow.io/spec/1.0.0/errors/validation)](dsl-reference.md#error). + +9. **Continue Workflow** +After the context is updated, the workflow continues to the next task in the sequence. The transformed output of the previous task is passed as the raw input to the next task, and the data flow cycle repeats. +If no more tasks are defined, the transformed output is passed to the workflow output transformation step. + +10. **Transform Workflow Output** +Finally, the overall workflow output can be transformed before it is returned to the caller or stored. Transformations are applied using the `output.as` runtime expression. It evaluates the last task's transformed output and defaults to the identity expression, which leaves the output unchanged. This step ensures that the final output of the workflow is concise and relevant, containing only the necessary information that needs to be communicated or recorded. + +*Example: If the workflow's final output is a summary report, a transformation can ensure that the report contains only the most important summaries and conclusions, excluding any intermediate data.* + +11. **Validate Workflow Output** +After `output.as` is evaluated, the transformed workflow output is validated against the `output.schema` property to ensure it conforms to the expected structure. The execution only proceeds if the output is valid. Otherwise, it will fault with a [ValidationError (https://serverlessworkflow.io/spec/1.0.0/errors/validation)](dsl-reference.md#error). + +By applying transformations at these strategic points, Serverless Workflow DSL ensures that data flows through the workflow in a controlled and efficient manner, maintaining clarity and relevance at each execution stage. This approach helps manage complex workflows and ensures that each task operates with the precise data required, leading to more predictable and reliable workflow outcomes. + +Visually, this can be represented as follows: + +```mermaid +flowchart TD + + subgraph Legend + legend_data{{Data}} + legend_schema[\Schema/] + legend_transformation[Transformation] + legend_arg([Runtime Argument]) + end + + initial_context_arg([
$context
])
+ context_arg([$context
])
+ input_arg([$input
])
+ output_arg([$output
])
+
+ workflow_raw_input{{Raw Workflow Input}}
+ workflow_input_schema[\Workflow: input.schema
/]
+ workflow_input_from[Workflow: input.from
]
+ workflow_transformed_input{{Transformed Workflow Input}}
+
+ task_raw_input{{Raw Task Input}}
+ task_if[Task: if
]
+ task_input_schema[\Task: input.schema
/]
+ task_input_from[Task: input.from
]
+ task_transformed_input{{Transformed Task Input}}
+ task_definition[Task definition]
+ task_raw_output{{Raw Task output}}
+ task_output_as[Task: output.as
]
+ task_transformed_output{{Transformed Task output}}
+ task_output_schema[\Task: output.schema
/]
+ task_export_as[Task: export.as
]
+ task_export_schema[\Task: export.schema
/]
+
+ new_context{{New execution context}}
+
+ workflow_raw_output{{Raw Workflow Output}}
+ workflow_output_as[Workflow: output.as
]
+ workflow_transformed_output{{Transformed Workflow Output}}
+ workflow_output_schema[\Workflow: output.schema
/]
+
+ workflow_raw_input -- Validated by --> workflow_input_schema
+ workflow_input_schema -- Passed to --> workflow_input_from
+ workflow_input_from -- Produces --> workflow_transformed_input
+ workflow_transformed_input -- Set as --> initial_context_arg
+ workflow_transformed_input -- Passed to --> task_raw_input
+
+ subgraph Task
+
+ task_raw_input -- Passed to --> task_if
+ task_if -- Validated by --> task_input_schema
+ task_input_schema -- Passed to --> task_input_from
+ task_input_from -- Produces --> task_transformed_input
+ task_transformed_input -- Set as --> input_arg
+ task_transformed_input -- Passed to --> task_definition
+
+ task_definition -- Execution produces --> task_raw_output
+ task_raw_output -- Passed to --> task_output_as
+ task_output_as -- Produces --> task_transformed_output
+ task_transformed_output -- Set as --> output_arg
+ task_transformed_output -- Validated by --> task_output_schema
+ task_output_schema -- Passed to --> task_export_as
+ task_export_as -- Produces --> new_context
+ new_context -- Validated by --> task_export_schema
+ end
+
+ task_transformed_output -- Passed as raw input to --> next_task
+
+ subgraph next_task [Next Task]
+ end
+
+ new_context -- set as --> context_arg
+
+ next_task -- Transformed output becomes --> workflow_raw_output
+ workflow_raw_output -- Passed to --> workflow_output_as
+ workflow_output_as -- Produces --> workflow_transformed_output
+ workflow_transformed_output -- Validated by --> workflow_output_schema
+```
+
+### Runtime Expressions
+
+Runtime expressions serve as dynamic elements that enable flexible and adaptable workflow behaviors. These expressions provide a means to evaluate conditions, transform data, and make decisions during the execution of workflows.
+
+Runtime expressions allow for the incorporation of variables, functions, and operators to create logic that responds to changing conditions and input data. These expressions can range from simple comparisons, such as checking if a variable meets a certain condition, to complex computations and transformations involving multiple variables and data sources.
+
+One key aspect of runtime expressions is their ability to adapt to runtime data and context. This means that expressions can access and manipulate data generated during the execution of a workflow, enabling dynamic decision-making and behavior based on real-time information.
+
+Runtime expressions in Serverless Workflow can be evaluated using either the default `strict` mode or the `loose` mode. In `strict` mode, all expressions must be properly identified with `${}` syntax. Conversely, in `loose` mode, expressions are evaluated more liberally, allowing for a wider range of input formats. While `strict` mode ensures strict adherence to syntax rules, `loose` mode offers flexibility, allowing evaluation even if the syntax is not perfectly formed.
+
+All runtimes **must** support the default runtime expression language, which is [`jq`](https://jqlang.github.io/jq/).
+
+Runtimes **may** optionally support other runtime expression languages, which authors can specifically use by adequately configuring the workflow. See [`evaluate.language`](dsl-reference.md#evaluate) for more details.
+
+CloudFlows defines [several arguments](#runtime-expression-arguments) that runtimes **must** provide during the evaluation of runtime expressions.
+
+When the evaluation of an expression fails, runtimes **must** raise an error with type `https://serverlessworkflow.io/spec/1.0.0/errors/expression` and status `400`.
+
+#### Runtime expression arguments
+
+| Name | Type | Description |
+|:-----|:----:|:------------|
+| context | `map` | The workflow's context data. |
+| input | `any` | The task's transformed input. |
+| output | `any` | The task's transformed output. |
+| secrets | `map` | A key/value map of the workflow secrets.
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "helloworld", - "version": "1.0.0", - "specVersion": "0.8", - "name": "Hello World Workflow", - "description": "Inject Hello World", - "start": "hello-state", - "states": [ - { - "name": "hello-state", - "type": "inject", - "data": { - "result": "Hello World!" - }, - "end": true - } - ] -}``` - - | -- -```yaml -id: helloworld -version: 1.0.0 -specVersion: "0.8" -name: Hello World Workflow -description: Inject Hello World -start: hello-state -states: - - name: hello-state - type: inject - data: - result: Hello World! - end: true -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "greeting", - "version": "1.0.0", - "specVersion": "0.8", - "name": "greeting-workflow", - "description": "Greet Someone", - "start": "greet", - "functions": [ - { - "name": "greeting-function", - "type": "openapi", - "operation": "file://myapis/greetingapis.json#greeting" - } - ], - "states": [ - { - "name": "greet", - "type": "operation", - "actions": [ - { - "name": "greet-action", - "functionRef": { - "refName": "greeting-function", - "arguments": { - "name": "${ .person.name }" - } - }, - "actionDataFilter": { - "results": "${ {greeting: .greeting} }" - } - } - ], - "end": true - } - ] -}``` - - | -- -```yaml -id: greeting -version: 1.0.0 -specVersion: "0.8" -name: greeting-workflow -description: Greet Someone -start: greet -functions: - - name: greeting-function - type: openapi - operation: file://myapis/greetingapis.json#greeting -states: - - name: greet - type: operation - actions: - - name: greet-action - functionRef: - refName: greeting-function - arguments: - name: ${ .person.name } - actionDataFilter: - results: "${ {greeting: .greeting} }" - end: true -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "eventbasedgreeting", - "version": "1.0.0", - "specVersion": "0.8", - "name": "Event Based Greeting Workflow", - "description": "Event Based Greeting", - "start": "greet", - "events": [ - { - "name": "greeting-event", - "type": "greetingEventType", - "source": "greetingEventSource" - } - ], - "functions": [ - { - "name": "greeting-function", - "operation": "file://myapis/greetingapis.json#greeting" - } - ], - "states": [ - { - "name": "greet", - "type": "event", - "onEvents": [ - { - "eventRefs": [ - "greeting-event" - ], - "eventDataFilter": { - "data": "${ .greet }", - "toStateData": "${ .greet }" - }, - "actions": [ - { - "name": "greet-action", - "functionRef": { - "refName": "greeting-function", - "arguments": { - "name": "${ .greet.name }" - } - } - } - ] - } - ], - "stateDataFilter": { - "output": "${ .payload.greeting }" - }, - "end": true - } - ] -}``` - - | -- -```yaml -id: eventbasedgreeting -version: 1.0.0 -specVersion: "0.8" -name: Event Based Greeting Workflow -description: Event Based Greeting -start: greet -events: - - name: greeting-event - type: greetingEventType - source: greetingEventSource -functions: - - name: greeting-function - operation: file://myapis/greetingapis.json#greeting -states: - - name: greet - type: event - onEvents: - - eventRefs: - - greeting-event - eventDataFilter: - data: ${ .greet } - toStateData: ${ .greet } - actions: - - name: greet-action - functionRef: - refName: greeting-function - arguments: - name: ${ .greet.name } - stateDataFilter: - output: ${ .payload.greeting } - end: true -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "solvemathproblems", - "version": "1.0.0", - "specVersion": "0.8", - "name": "solve-math-problems-workflow", - "description": "Solve math problems", - "start": "solve", - "functions": [ - { - "name": "solve-math-exp-func", - "operation": "http://myapis.org/mapthapis.json#solveExpression" - } - ], - "states": [ - { - "name": "solve", - "type": "foreach", - "inputCollection": "${ .expressions }", - "iterationParam": "singleexpression", - "outputCollection": "${ .results }", - "actions": [ - { - "name": "solve-action", - "functionRef": { - "refName": "solve-math-exp-func", - "arguments": { - "expression": "${ .singleexpression }" - } - } - } - ], - "stateDataFilter": { - "output": "${ .results }" - }, - "end": true - } - ] -}``` - - | -- -```yaml -id: solvemathproblems -version: 1.0.0 -specVersion: "0.8" -name: solve-math-problems-workflow -description: Solve math problems -start: solve -functions: - - name: solve-math-exp-func - operation: http://myapis.org/mapthapis.json#solveExpression -states: - - name: solve - type: foreach - inputCollection: ${ .expressions } - iterationParam: singleexpression - outputCollection: ${ .results } - actions: - - name: solve-action - functionRef: - refName: solve-math-exp-func - arguments: - expression: ${ .singleexpression } - stateDataFilter: - output: ${ .results } - end: true -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "parallelexec", - "version": "1.0.0", - "specVersion": "0.8", - "name": "parallel-execution", - "description": "Executes two branches in parallel", - "start": "parallelexec", - "states": [ - { - "name": "parallelexec", - "type": "parallel", - "completionType": "allOf", - "branches": [ - { - "name": "short-delay-branch", - "actions": [ - { - "name": "short-delay-action", - "subFlowRef": "shortdelayworkflowid" - } - ] - }, - { - "name": "long-delay-branch", - "actions": [ - { - "name": "short-delay-action", - "subFlowRef": "longdelayworkflowid" - } - ] - } - ], - "end": true - } - ] -}``` - - | -- -```yaml -id: parallelexec -version: 1.0.0 -specVersion: "0.8" -name: parallel-execution -description: Executes two branches in parallel -start: parallelexec -states: - - name: parallelexec - type: parallel - completionType: allOf - branches: - - name: short-delay-branch - actions: - - name: short-delay-action - subFlowRef: shortdelayworkflowid - - name: long-delay-branch - actions: - - name: short-delay-action - subFlowRef: longdelayworkflowid - end: true -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "sendcustomeremail", - "version": "1.0.0", - "specVersion": "0.8", - "name": "send-customer-email-workflow", - "description": "Send email to a customer", - "start": "send-email", - "functions": [ - { - "name": "email-function", - "operation": "file://myapis/emailapis.json#sendEmail" - } - ], - "states": [ - { - "name": "send-email", - "type": "operation", - "actions": [ - { - "name": "send-email-action", - "functionRef": { - "invoke": "async", - "refName": "email-function", - "arguments": { - "customer": "${ .customer }" - } - } - } - ], - "end": true - } - ] -}``` - - | -- -```yaml -id: sendcustomeremail -version: 1.0.0 -specVersion: "0.8" -name: send-customer-email-workflow -description: Send email to a customer -start: send-email -functions: - - name: email-function - operation: file://myapis/emailapis.json#sendEmail -states: - - name: send-email - type: operation - actions: - - name: send-email-action - functionRef: - invoke: async - refName: email-function - arguments: - customer: ${ .customer } - end: true -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "onboardcustomer", - "version": "1.0.0", - "specVersion": "0.8", - "name": "onboard-customer", - "description": "Onboard a Customer", - "start": "onboard", - "states": [ - { - "name": "onboard", - "type": "operation", - "actions": [ - { - "name": "onboard-action", - "subFlowRef": { - "invoke": "async", - "onParentComplete": "continue", - "workflowId": "customeronboardingworkflow", - "version": "1.0.0" - } - } - ], - "end": true - } - ] -}``` - - | -- -```yaml -id: onboardcustomer -version: 1.0.0 -specVersion: "0.8" -name: onboard-customer -description: Onboard a Customer -start: onboard -states: - - name: onboard - type: operation - actions: - - name: onboard-action - subFlowRef: - invoke: async - onParentComplete: continue - workflowId: customeronboardingworkflow - version: 1.0.0 - end: true -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "eventbasedswitchstate", - "version": "1.0.0", - "specVersion": "0.8", - "name": "event-based-switch-transitions", - "description": "Event Based Switch Transitions", - "start": "checkvisastatus", - "events": [ - { - "name": "visa-approved-event", - "type": "VisaApproved", - "source": "visaCheckSource" - }, - { - "name": "visa-rejected-event", - "type": "VisaRejected", - "source": "visaCheckSource" - } - ], - "states": [ - { - "name": "checkvisastatus", - "type": "switch", - "eventConditions": [ - { - "eventRef": "visa-approved-event", - "transition": "handle-approved-visa", - "name": "approved-condition" - }, - { - "eventRef": "visa-rejected-event", - "transition": "handle-rejected-visa", - "name": "rejected-condition" - } - ], - "timeouts": { - "eventTimeout": "PT1H" - }, - "defaultCondition": { - "transition": "handle-no-visa-decision" - } - }, - { - "name": "handle-approved-visa", - "type": "operation", - "actions": [ - { - "name": "handle-approved-action", - "subFlowRef": "handleApprovedVisaWorkflowID" - } - ], - "end": true - }, - { - "name": "handle-rejected-visa", - "type": "operation", - "actions": [ - { - "name": "handle-rejected-action", - "subFlowRef": "handleRejectedVisaWorkflowID" - } - ], - "end": true - }, - { - "name": "handle-no-visa-decision", - "type": "operation", - "actions": [ - { - "name": "handle-novisa-action", - "subFlowRef": "handleNoVisaDecisionWorkflowId" - } - ], - "end": true - } - ] -}``` - - | -- -```yaml -id: eventbasedswitchstate -version: 1.0.0 -specVersion: "0.8" -name: event-based-switch-transitions -description: Event Based Switch Transitions -start: checkvisastatus -events: - - name: visa-approved-event - type: VisaApproved - source: visaCheckSource - - name: visa-rejected-event - type: VisaRejected - source: visaCheckSource -states: - - name: checkvisastatus - type: switch - eventConditions: - - eventRef: visa-approved-event - transition: handle-approved-visa - name: approved-condition - - eventRef: visa-rejected-event - transition: handle-rejected-visa - name: rejected-condition - timeouts: - eventTimeout: PT1H - defaultCondition: - transition: handle-no-visa-decision - - name: handle-approved-visa - type: operation - actions: - - name: handle-approved-action - subFlowRef: handleApprovedVisaWorkflowID - end: true - - name: handle-rejected-visa - type: operation - actions: - - name: handle-rejected-action - subFlowRef: handleRejectedVisaWorkflowID - end: true - - name: handle-no-visa-decision - type: operation - actions: - - name: handle-novisa-action - subFlowRef: handleNoVisaDecisionWorkflowId - end: true -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "applicantrequest", - "version": "1.0.0", - "specVersion": "0.8", - "name": "applicant-request-decision-workflow", - "description": "Determine if applicant request is valid", - "start": "check-application", - "functions": [ - { - "name": "send-rejection-email-function", - "operation": "http://myapis.org/applicationapi.json#emailRejection" - } - ], - "states": [ - { - "name": "check-application", - "type": "switch", - "dataConditions": [ - { - "condition": "${ .applicants | .age >= 18 }", - "transition": "start-application", - "name": "adult-condition" - }, - { - "condition": "${ .applicants | .age < 18 }", - "transition": "reject-application", - "name": "minor-condition" - } - ], - "defaultCondition": { - "transition": "reject-application" - } - }, - { - "name": "start-application", - "type": "operation", - "actions": [ - { - "name": "start-app-action", - "subFlowRef": "startApplicationWorkflowId" - } - ], - "end": true - }, - { - "name": "reject-application", - "type": "operation", - "actionMode": "sequential", - "actions": [ - { - "name": "send-reject-action", - "functionRef": { - "refName": "send-rejection-email-function", - "arguments": { - "applicant": "${ .applicant }" - } - } - } - ], - "end": true - } - ] -}``` - - | -- -```yaml -id: applicantrequest -version: 1.0.0 -specVersion: "0.8" -name: applicant-request-decision-workflow -description: Determine if applicant request is valid -start: check-application -functions: - - name: send-rejection-email-function - operation: http://myapis.org/applicationapi.json#emailRejection -states: - - name: check-application - type: switch - dataConditions: - - condition: ${ .applicants | .age >= 18 } - transition: start-application - name: adult-condition - - condition: ${ .applicants | .age < 18 } - transition: reject-application - name: minor-condition - defaultCondition: - transition: reject-application - - name: start-application - type: operation - actions: - - name: start-app-action - subFlowRef: startApplicationWorkflowId - end: true - - name: reject-application - type: operation - actionMode: sequential - actions: - - name: send-reject-action - functionRef: - refName: send-rejection-email-function - arguments: - applicant: ${ .applicant } - end: true -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "provisionorders", - "version": "1.0.0", - "specVersion": "0.8", - "name": "provision-orders", - "description": "Provision Orders and handle errors thrown", - "start": "provision-order", - "functions": [ - { - "name": "provision-order-function", - "operation": "http://myapis.org/provisioningapi.json#doProvision" - } - ], - "errors": [ - { - "name": "missing-order-id" - }, - { - "name": "missing-order-item" - }, - { - "name": "missing-order-quantity" - } - ], - "states": [ - { - "name": "provision-order", - "type": "operation", - "actionMode": "sequential", - "actions": [ - { - "name": "provision-action", - "functionRef": { - "refName": "provision-order-function", - "arguments": { - "order": "${ .order }" - } - } - } - ], - "stateDataFilter": { - "output": "${ .exceptions }" - }, - "transition": "apply-order", - "onErrors": [ - { - "errorRef": "missing-order-id", - "transition": "missing-id" - }, - { - "errorRef": "missing-order-item", - "transition": "missing-item" - }, - { - "errorRef": "missing-order-quantity", - "transition": "missing-quantity" - } - ] - }, - { - "name": "missing-id", - "type": "operation", - "actions": [ - { - "name": "missing-action", - "subFlowRef": "handleMissingIdExceptionWorkflow" - } - ], - "end": true - }, - { - "name": "missing-item", - "type": "operation", - "actions": [ - { - "name": "missing-item", - "subFlowRef": "handleMissingItemExceptionWorkflow" - } - ], - "end": true - }, - { - "name": "missing-quantity", - "type": "operation", - "actions": [ - { - "name": "missing-quantity", - "subFlowRef": "handleMissingQuantityExceptionWorkflow" - } - ], - "end": true - }, - { - "name": "apply-order", - "type": "operation", - "actions": [ - { - "name": "apply-order", - "subFlowRef": "applyOrderWorkflowId" - } - ], - "end": true - } - ] -}``` - - | -- -```yaml -id: provisionorders -version: 1.0.0 -specVersion: "0.8" -name: provision-orders -description: Provision Orders and handle errors thrown -start: provision-order -functions: - - name: provision-order-function - operation: http://myapis.org/provisioningapi.json#doProvision -errors: - - name: missing-order-id - - name: missing-order-item - - name: missing-order-quantity -states: - - name: provision-order - type: operation - actionMode: sequential - actions: - - name: provision-action - functionRef: - refName: provision-order-function - arguments: - order: ${ .order } - stateDataFilter: - output: ${ .exceptions } - transition: apply-order - onErrors: - - errorRef: missing-order-id - transition: missing-id - - errorRef: missing-order-item - transition: missing-item - - errorRef: missing-order-quantity - transition: missing-quantity - - name: missing-id - type: operation - actions: - - name: missing-action - subFlowRef: handleMissingIdExceptionWorkflow - end: true - - name: missing-item - type: operation - actions: - - name: missing-item - subFlowRef: handleMissingItemExceptionWorkflow - end: true - - name: missing-quantity - type: operation - actions: - - name: missing-quantity - subFlowRef: handleMissingQuantityExceptionWorkflow - end: true - - name: apply-order - type: operation - actions: - - name: apply-order - subFlowRef: applyOrderWorkflowId - end: true -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "jobmonitoring", - "version": "1.0.0", - "specVersion": "0.8", - "name": "jobmonitoring", - "description": "Monitor finished execution of a submitted job", - "start": "submit-job", - "functions": [ - { - "name": "submit-job", - "operation": "http://myapis.org/monitorapi.json#doSubmit" - }, - { - "name": "check-job-status", - "operation": "http://myapis.org/monitorapi.json#checkStatus" - }, - { - "name": "report-job-suceeded", - "operation": "http://myapis.org/monitorapi.json#reportSucceeded" - }, - { - "name": "report-job-failed", - "operation": "http://myapis.org/monitorapi.json#reportFailure" - } - ], - "states": [ - { - "name": "submit-job", - "type": "operation", - "actionMode": "sequential", - "actions": [ - { - "name": "submit-job", - "functionRef": { - "refName": "submit-job", - "arguments": { - "name": "${ .job.name }" - } - }, - "actionDataFilter": { - "results": "${ .jobuid }" - } - } - ], - "stateDataFilter": { - "output": "${ .jobuid }" - }, - "transition": "wait-for-completion" - }, - { - "name": "wait-for-completion", - "type": "sleep", - "duration": "PT5S", - "transition": "get-job-status" - }, - { - "name": "get-job-status", - "type": "operation", - "actionMode": "sequential", - "actions": [ - { - "name": "get-job-status", - "functionRef": { - "refName": "check-job-status", - "arguments": { - "name": "${ .jobuid }" - } - }, - "actionDataFilter": { - "results": "${ .jobstatus }" - } - } - ], - "stateDataFilter": { - "output": "${ .jobstatus }" - }, - "transition": "determine-completion" - }, - { - "name": "determine-completion", - "type": "switch", - "dataConditions": [ - { - "condition": "${ .jobStatus == \"SUCCEEDED\" }", - "transition": "job-succeeded", - "name": "succeed" - }, - { - "condition": "${ .jobStatus == \"FAILED\" }", - "transition": "job-failed", - "name": "failed" - } - ], - "defaultCondition": { - "transition": "wait-for-completion" - } - }, - { - "name": "job-succeeded", - "type": "operation", - "actionMode": "sequential", - "actions": [ - { - "name": "job-succeeded", - "functionRef": { - "refName": "report-job-suceeded", - "arguments": { - "name": "${ .jobuid }" - } - } - } - ], - "end": true - }, - { - "name": "job-failed", - "type": "operation", - "actionMode": "sequential", - "actions": [ - { - "name": "job-failed", - "functionRef": { - "refName": "report-job-failed", - "arguments": { - "name": "${ .jobuid }" - } - } - } - ], - "end": true - } - ] -}``` - - | -- -```yaml -id: jobmonitoring -version: 1.0.0 -specVersion: "0.8" -name: jobmonitoring -description: Monitor finished execution of a submitted job -start: submit-job -functions: - - name: submit-job - operation: http://myapis.org/monitorapi.json#doSubmit - - name: check-job-status - operation: http://myapis.org/monitorapi.json#checkStatus - - name: report-job-suceeded - operation: http://myapis.org/monitorapi.json#reportSucceeded - - name: report-job-failed - operation: http://myapis.org/monitorapi.json#reportFailure -states: - - name: submit-job - type: operation - actionMode: sequential - actions: - - name: submit-job - functionRef: - refName: submit-job - arguments: - name: ${ .job.name } - actionDataFilter: - results: ${ .jobuid } - stateDataFilter: - output: ${ .jobuid } - transition: wait-for-completion - - name: wait-for-completion - type: sleep - duration: PT5S - transition: get-job-status - - name: get-job-status - type: operation - actionMode: sequential - actions: - - name: get-job-status - functionRef: - refName: check-job-status - arguments: - name: ${ .jobuid } - actionDataFilter: - results: ${ .jobstatus } - stateDataFilter: - output: ${ .jobstatus } - transition: determine-completion - - name: determine-completion - type: switch - dataConditions: - - condition: ${ .jobStatus == "SUCCEEDED" } - transition: job-succeeded - name: succeed - - condition: ${ .jobStatus == "FAILED" } - transition: job-failed - name: failed - defaultCondition: - transition: wait-for-completion - - name: job-succeeded - type: operation - actionMode: sequential - actions: - - name: job-succeeded - functionRef: - refName: report-job-suceeded - arguments: - name: ${ .jobuid } - end: true - - name: job-failed - type: operation - actionMode: sequential - actions: - - name: job-failed - functionRef: - refName: report-job-failed - arguments: - name: ${ .jobuid } - end: true -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "sendcloudeventonprovision", - "version": "1.0.0", - "specVersion": "0.8", - "name": "sendcloudeventonprovision", - "start": "provision-orders-state", - "events": [ - { - "name": "provisioning-complete-event", - "type": "provisionCompleteType", - "kind": "produced" - } - ], - "functions": [ - { - "name": "provision-order-function", - "operation": "http://myapis.org/provisioning.json#doProvision" - } - ], - "states": [ - { - "name": "provision-orders-state", - "type": "foreach", - "inputCollection": "${ .orders }", - "iterationParam": "singleorder", - "outputCollection": "${ .provisionedOrders }", - "actions": [ - { - "name": "provision-order-function", - "functionRef": { - "refName": "provision-order-function", - "arguments": { - "order": "${ .singleorder }" - } - } - } - ], - "end": { - "produceEvents": [ - { - "eventRef": "provisioning-complete-event", - "data": "${ .provisionedOrders }" - } - ] - } - } - ] -}``` - - | -- -```yaml -id: sendcloudeventonprovision -version: 1.0.0 -specVersion: "0.8" -name: sendcloudeventonprovision -start: provision-orders-state -events: - - name: provisioning-complete-event - type: provisionCompleteType - kind: produced -functions: - - name: provision-order-function - operation: http://myapis.org/provisioning.json#doProvision -states: - - name: provision-orders-state - type: foreach - inputCollection: ${ .orders } - iterationParam: singleorder - outputCollection: ${ .provisionedOrders } - actions: - - name: provision-order-function - functionRef: - refName: provision-order-function - arguments: - order: ${ .singleorder } - end: - produceEvents: - - eventRef: provisioning-complete-event - data: ${ .provisionedOrders } -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "patientVitalsWorkflow", - "name": "patientVitalsWorkflow", - "version": "1.0.0", - "specVersion": "0.8", - "start": "monitor-vitals", - "events": [ - { - "name": "high-body-temperature", - "type": "org.monitor.highBodyTemp", - "source": "monitoringSource", - "correlation": [ - { - "contextAttributeName": "patientId" - } - ] - }, - { - "name": "high-blood-pressure", - "type": "org.monitor.highBloodPressure", - "source": "monitoringSource", - "correlation": [ - { - "contextAttributeName": "patientId" - } - ] - }, - { - "name": "high-respiration-rate", - "type": "org.monitor.highRespirationRate", - "source": "monitoringSource", - "correlation": [ - { - "contextAttributeName": "patientId" - } - ] - } - ], - "functions": [ - { - "name": "call-pulmonologist", - "operation": "http://myapis.org/patientapis.json#callPulmonologist" - }, - { - "name": "send-tylenol-order", - "operation": "http://myapis.org/patientapis.json#tylenolOrder" - }, - { - "name": "call-nurse", - "operation": "http://myapis.org/patientapis.json#callNurse" - } - ], - "states": [ - { - "name": "monitor-vitals", - "type": "event", - "exclusive": true, - "onEvents": [ - { - "eventRefs": [ - "high-body-temperature" - ], - "actions": [ - { - "name": "send-tylenol-order", - "functionRef": { - "refName": "send-tylenol-order", - "arguments": { - "patientid": "${ .patientId }" - } - } - } - ] - }, - { - "eventRefs": [ - "high-blood-pressure" - ], - "actions": [ - { - "name": "call-nurse", - "functionRef": { - "refName": "call-nurse", - "arguments": { - "patientid": "${ .patientId }" - } - } - } - ] - }, - { - "eventRefs": [ - "high-respiration-rate" - ], - "actions": [ - { - "name": "call-pulmonologist", - "functionRef": { - "refName": "call-pulmonologist", - "arguments": { - "patientid": "${ .patientId }" - } - } - } - ] - } - ], - "end": { - "terminate": true - } - } - ] -}``` - - | -- -```yaml -id: patientVitalsWorkflow -name: patientVitalsWorkflow -version: 1.0.0 -specVersion: "0.8" -start: monitor-vitals -events: - - name: high-body-temperature - type: org.monitor.highBodyTemp - source: monitoringSource - correlation: - - contextAttributeName: patientId - - name: high-blood-pressure - type: org.monitor.highBloodPressure - source: monitoringSource - correlation: - - contextAttributeName: patientId - - name: high-respiration-rate - type: org.monitor.highRespirationRate - source: monitoringSource - correlation: - - contextAttributeName: patientId -functions: - - name: call-pulmonologist - operation: http://myapis.org/patientapis.json#callPulmonologist - - name: send-tylenol-order - operation: http://myapis.org/patientapis.json#tylenolOrder - - name: call-nurse - operation: http://myapis.org/patientapis.json#callNurse -states: - - name: monitor-vitals - type: event - exclusive: true - onEvents: - - eventRefs: - - high-body-temperature - actions: - - name: send-tylenol-order - functionRef: - refName: send-tylenol-order - arguments: - patientid: ${ .patientId } - - eventRefs: - - high-blood-pressure - actions: - - name: call-nurse - functionRef: - refName: call-nurse - arguments: - patientid: ${ .patientId } - - eventRefs: - - high-respiration-rate - actions: - - name: call-pulmonologist - functionRef: - refName: call-pulmonologist - arguments: - patientid: ${ .patientId } - end: - terminate: true -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "finalize-college-application", - "name": "finalizeCollegeApplication", - "version": "1.0.0", - "specVersion": "0.8", - "start": "finalize-application", - "events": [ - { - "name": "application-submitted", - "type": "org.application.submitted", - "source": "applicationsource", - "correlation": [ - { - "contextAttributeName": "applicantId" - } - ] - }, - { - "name": "sat-scores-received", - "type": "org.application.satscores", - "source": "applicationsource", - "correlation": [ - { - "contextAttributeName": "applicantId" - } - ] - }, - { - "name": "recommendation-letter-received", - "type": "org.application.recommendationLetter", - "source": "applicationsource", - "correlation": [ - { - "contextAttributeName": "applicantId" - } - ] - } - ], - "functions": [ - { - "name": "finalize-application-function", - "operation": "http://myapis.org/collegeapplicationapi.json#finalize" - } - ], - "states": [ - { - "name": "finalize-application", - "type": "event", - "exclusive": false, - "onEvents": [ - { - "eventRefs": [ - "application-submitted", - "sat-scores-received", - "recommendation-letter-received" - ], - "actions": [ - { - "name": "finalize-application", - "functionRef": { - "refName": "finalize-application-function", - "arguments": { - "student": "${ .applicantId }" - } - } - } - ] - } - ], - "end": { - "terminate": true - } - } - ] -}``` - - | -- -```yaml -id: finalize-college-application -name: finalizeCollegeApplication -version: 1.0.0 -specVersion: "0.8" -start: finalize-application -events: - - name: application-submitted - type: org.application.submitted - source: applicationsource - correlation: - - contextAttributeName: applicantId - - name: sat-scores-received - type: org.application.satscores - source: applicationsource - correlation: - - contextAttributeName: applicantId - - name: recommendation-letter-received - type: org.application.recommendationLetter - source: applicationsource - correlation: - - contextAttributeName: applicantId -functions: - - name: finalize-application-function - operation: http://myapis.org/collegeapplicationapi.json#finalize -states: - - name: finalize-application - type: event - exclusive: false - onEvents: - - eventRefs: - - application-submitted - - sat-scores-received - - recommendation-letter-received - actions: - - name: finalize-application - functionRef: - refName: finalize-application-function - arguments: - student: ${ .applicantId } - end: - terminate: true -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "customercreditcheck", - "version": "1.0.0", - "specVersion": "0.8", - "name": "customercreditcheck", - "description": "Perform Customer Credit Check", - "start": "check-credit", - "functions": [ - { - "name": "credit-check-function", - "operation": "http://myapis.org/creditcheckapi.json#doCreditCheck" - }, - { - "name": "send-rejection-email-function", - "operation": "http://myapis.org/creditcheckapi.json#rejectionEmail" - } - ], - "events": [ - { - "name": "credit-check-completed-event", - "type": "creditCheckCompleteType", - "source": "creditCheckSource", - "correlation": [ - { - "contextAttributeName": "customerId" - } - ] - } - ], - "states": [ - { - "name": "check-credit", - "type": "callback", - "action": { - "name": "check-credit", - "functionRef": { - "refName": "call-credit-check-microservice", - "arguments": { - "customer": "${ .customer }" - } - } - }, - "eventRef": "credit-check-completed-event", - "timeouts": { - "stateExecTimeout": "PT15M" - }, - "transition": "evaluate-decision" - }, - { - "name": "evaluate-decision", - "type": "switch", - "dataConditions": [ - { - "condition": "${ .creditCheck | .decision == \"Approved\" }", - "transition": "start-application", - "name": "start-application" - }, - { - "condition": "${ .creditCheck | .decision == \"Denied\" }", - "transition": "reject-application", - "name": "reject-application" - } - ], - "defaultCondition": { - "transition": "reject-application" - } - }, - { - "name": "start-application", - "type": "operation", - "actions": [ - { - "name": "start-application", - "subFlowRef": "startApplicationWorkflowId" - } - ], - "end": true - }, - { - "name": "reject-application", - "type": "operation", - "actionMode": "sequential", - "actions": [ - { - "name": "reject-application", - "functionRef": { - "refName": "send-rejection-email-function", - "arguments": { - "applicant": "${ .customer }" - } - } - } - ], - "end": true - } - ] -}``` - - | -- -```yaml -id: customercreditcheck -version: 1.0.0 -specVersion: "0.8" -name: customercreditcheck -description: Perform Customer Credit Check -start: check-credit -functions: - - name: credit-check-function - operation: http://myapis.org/creditcheckapi.json#doCreditCheck - - name: send-rejection-email-function - operation: http://myapis.org/creditcheckapi.json#rejectionEmail -events: - - name: credit-check-completed-event - type: creditCheckCompleteType - source: creditCheckSource - correlation: - - contextAttributeName: customerId -states: - - name: check-credit - type: callback - action: - name: check-credit - functionRef: - refName: call-credit-check-microservice - arguments: - customer: ${ .customer } - eventRef: credit-check-completed-event - timeouts: - stateExecTimeout: PT15M - transition: evaluate-decision - - name: evaluate-decision - type: switch - dataConditions: - - condition: ${ .creditCheck | .decision == "Approved" } - transition: start-application - name: start-application - - condition: ${ .creditCheck | .decision == "Denied" } - transition: reject-application - name: reject-application - defaultCondition: - transition: reject-application - - name: start-application - type: operation - actions: - - name: start-application - subFlowRef: startApplicationWorkflowId - end: true - - name: reject-application - type: operation - actionMode: sequential - actions: - - name: reject-application - functionRef: - refName: send-rejection-email-function - arguments: - applicant: ${ .customer } - end: true -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "handle-car-auction-bid", - "version": "1.0.0", - "specVersion": "0.8", - "name": "handle-car-auction-bid", - "description": "Store a single bid whole the car auction is active", - "start": { - "stateName": "store-car-auction-bid", - "schedule": "R/PT2H" - }, - "functions": [ - { - "name": "store-bid-function", - "operation": "http://myapis.org/carauctionapi.json#storeBid" - } - ], - "events": [ - { - "name": "car-bid-event", - "type": "carBidMadeType", - "source": "carBidEventSource" - } - ], - "states": [ - { - "name": "store-car-auction-bid", - "type": "event", - "exclusive": true, - "onEvents": [ - { - "eventRefs": [ - "car-bid-event" - ], - "actions": [ - { - "name": "car-bid-event", - "functionRef": { - "refName": "store-bid-function", - "arguments": { - "bid": "${ .bid }" - } - } - } - ] - } - ], - "end": true - } - ] -}``` - - | -- -```yaml -id: handle-car-auction-bid -version: 1.0.0 -specVersion: "0.8" -name: handle-car-auction-bid -description: Store a single bid whole the car auction is active -start: - stateName: store-car-auction-bid - schedule: R/PT2H -functions: - - name: store-bid-function - operation: http://myapis.org/carauctionapi.json#storeBid -events: - - name: car-bid-event - type: carBidMadeType - source: carBidEventSource -states: - - name: store-car-auction-bid - type: event - exclusive: true - onEvents: - - eventRefs: - - car-bid-event - actions: - - name: car-bid-event - functionRef: - refName: store-bid-function - arguments: - bid: ${ .bid } - end: true -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "check-inbox", - "name": "check-inbox", - "version": "1.0.0", - "specVersion": "0.8", - "description": "Periodically Check Inbox", - "start": { - "stateName": "check-inbox", - "schedule": { - "cron": "0 0/15 * * * ?" - } - }, - "functions": [ - { - "name": "check-inbox-function", - "operation": "http://myapis.org/inboxapi.json#checkNewMessages" - }, - { - "name": "send-text-function", - "operation": "http://myapis.org/inboxapi.json#sendText" - } - ], - "states": [ - { - "name": "check-inbox", - "type": "operation", - "actionMode": "sequential", - "actions": [ - { - "name":"check-inbox", - "functionRef": "check-inbox-function" - } - ], - "transition": "send-text-for-high-priority" - }, - { - "name": "send-text-for-high-priority", - "type": "foreach", - "inputCollection": "${ .messages }", - "iterationParam": "singlemessage", - "actions": [ - { - "name": "send-text-for-high-priority", - "functionRef": { - "refName": "send-text-function", - "arguments": { - "message": "${ .singlemessage }" - } - } - } - ], - "end": true - } - ] -}``` - - | -- -```yaml -id: check-inbox -name: check-inbox -version: 1.0.0 -specVersion: "0.8" -description: Periodically Check Inbox -start: - stateName: check-inbox - schedule: - cron: 0 0/15 * * * ? -functions: - - name: check-inbox-function - operation: http://myapis.org/inboxapi.json#checkNewMessages - - name: send-text-function - operation: http://myapis.org/inboxapi.json#sendText -states: - - name: check-inbox - type: operation - actionMode: sequential - actions: - - name: check-inbox - functionRef: check-inbox-function - transition: send-text-for-high-priority - - name: send-text-for-high-priority - type: foreach - inputCollection: ${ .messages } - iterationParam: singlemessage - actions: - - name: send-text-for-high-priority - functionRef: - refName: send-text-function - arguments: - message: ${ .singlemessage } - end: true -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "vet-appointment-workflow", - "name": "vet-appointment-workflow", - "description": "Vet service call via events", - "version": "1.0.0", - "specVersion": "0.8", - "start": "make-vet-appointment-state", - "events": [ - { - "name": "make-vet-appointment", - "source": "VetServiceSource", - "type": "events.vet.appointments", - "kind": "produced" - }, - { - "name": "vet-appointment-info", - "source": "VetServiceSource", - "type": "events.vet.appointments", - "kind": "consumed" - } - ], - "states": [ - { - "name": "make-vet-appointment-state", - "type": "operation", - "actions": [ - { - "name": "make-appointment-action", - "eventRef": { - "produceEventRef": "make-vet-appointment", - "data": "${ .patientInfo }", - "consumeEventRef": "vet-appointment-info" - }, - "actionDataFilter": { - "results": "${ .appointmentInfo }" - } - } - ], - "timeouts": { - "actionExecTimeout": "PT15M" - }, - "end": true - } - ] -}``` - - | -- -```yaml -id: vet-appointment-workflow -name: vet-appointment-workflow -description: Vet service call via events -version: 1.0.0 -specVersion: "0.8" -start: make-vet-appointment-state -events: - - name: make-vet-appointment - source: VetServiceSource - type: events.vet.appointments - kind: produced - - name: vet-appointment-info - source: VetServiceSource - type: events.vet.appointments - kind: consumed -states: - - name: make-vet-appointment-state - type: operation - actions: - - name: make-appointment-action - eventRef: - produceEventRef: make-vet-appointment - data: ${ .patientInfo } - consumeEventRef: vet-appointment-info - actionDataFilter: - results: ${ .appointmentInfo } - timeouts: - actionExecTimeout: PT15M - end: true -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "paymentconfirmation", - "version": "1.0.0", - "specVersion": "0.8", - "name": "paymentconfirmation", - "description": "Performs Payment Confirmation", - "functions": "file://functiondefs.json", - "events": "file://eventdefs.yml", - "states": [ - { - "name": "payment-received", - "type": "event", - "onEvents": [ - { - "eventRefs": [ - "payment-received-event" - ], - "actions": [ - { - "name": "checkfunds", - "functionRef": { - "refName": "check-funds-availability", - "arguments": { - "account": "${ .accountId }", - "paymentamount": "${ .payment.amount }" - } - } - } - ] - } - ], - "transition": "confirm-based-on-funds" - }, - { - "name": "confirm-based-on-funds", - "type": "switch", - "dataConditions": [ - { - "condition": "${ .funds | .available == \"true\" }", - "transition": "send-payment-success", - "name": "success" - }, - { - "condition": "${ .funds | .available == \"false\" }", - "transition": "send-insufficient-results", - "name": "failed" - } - ], - "defaultCondition": { - "transition": "send-payment-success" - } - }, - { - "name": "send-payment-success", - "type": "operation", - "actions": [ - { - "name": "send-payment-success", - "functionRef": { - "refName": "send-success-email", - "arguments": { - "applicant": "${ .customer }" - } - } - } - ], - "end": { - "produceEvents": [ - { - "eventRef": "confirmation-completed-event", - "data": "${ .payment }" - } - ] - } - }, - { - "name": "send-insufficient-results", - "type": "operation", - "actions": [ - { - "name": "send-insufficient-results", - "functionRef": { - "refName": "send-insufficient-funds-email", - "arguments": { - "applicant": "${ .customer }" - } - } - } - ], - "end": { - "produceEvents": [ - { - "eventRef": "confirmation-completed-event", - "data": "${ .payment }" - } - ] - } - } - ] -}``` - - | -- -```yaml -id: paymentconfirmation -version: 1.0.0 -specVersion: "0.8" -name: paymentconfirmation -description: Performs Payment Confirmation -functions: file://functiondefs.json -events: file://eventdefs.yml -states: - - name: payment-received - type: event - onEvents: - - eventRefs: - - payment-received-event - actions: - - name: checkfunds - functionRef: - refName: check-funds-availability - arguments: - account: ${ .accountId } - paymentamount: ${ .payment.amount } - transition: confirm-based-on-funds - - name: confirm-based-on-funds - type: switch - dataConditions: - - condition: ${ .funds | .available == "true" } - transition: send-payment-success - name: success - - condition: ${ .funds | .available == "false" } - transition: send-insufficient-results - name: failed - defaultCondition: - transition: send-payment-success - - name: send-payment-success - type: operation - actions: - - name: send-payment-success - functionRef: - refName: send-success-email - arguments: - applicant: ${ .customer } - end: - produceEvents: - - eventRef: confirmation-completed-event - data: ${ .payment } - - name: send-insufficient-results - type: operation - actions: - - name: send-insufficient-results - functionRef: - refName: send-insufficient-funds-email - arguments: - applicant: ${ .customer } - end: - produceEvents: - - eventRef: confirmation-completed-event - data: ${ .payment } -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "patientonboarding", - "name": "patientonboarding", - "version": "1.0.0", - "specVersion": "0.8", - "start": "onboard", - "states": [ - { - "name": "onboard", - "type": "event", - "onEvents": [ - { - "eventRefs": [ - "new-patient-event" - ], - "actions": [ - { - "name": "store-patient", - "functionRef": "store-patient", - "retryRef": "services-not-available-retry-strategy", - "retryableErrors": [ - "service-not-available" - ] - }, - { - "name": "assign-doctor", - "functionRef": "assign-doctor", - "retryRef": "services-not-available-retry-strategy", - "retryableErrors": [ - "service-not-available" - ] - }, - { - "name": "schedule-appt", - "functionRef": "schedule-appt", - "retryRef": "services-not-available-retry-strategy", - "retryableErrors": [ - "service-not-available" - ] - } - ] - } - ], - "onErrors": [ - { - "errorRef": "service-not-available", - "end": true - } - ], - "end": true - } - ], - "events": [ - { - "name": "store-patient", - "type": "new.patients.event", - "source": "newpatient/+" - } - ], - "functions": [ - { - "name": "store-new-patient-info", - "operation": "api/services.json#addPatient" - }, - { - "name": "assign-doctor", - "operation": "api/services.json#assignDoctor" - }, - { - "name": "schedule-appt", - "operation": "api/services.json#scheduleAppointment" - } - ], - "errors": [ - { - "name": "service-not-available", - "code": "503" - } - ], - "retries": [ - { - "name": "services-not-available-retry-strategy", - "delay": "PT3S", - "maxAttempts": 10 - } - ] -}``` - - | -- -```yaml -id: patientonboarding -name: patientonboarding -version: 1.0.0 -specVersion: "0.8" -start: onboard -states: - - name: onboard - type: event - onEvents: - - eventRefs: - - new-patient-event - actions: - - name: store-patient - functionRef: store-patient - retryRef: services-not-available-retry-strategy - retryableErrors: - - service-not-available - - name: assign-doctor - functionRef: assign-doctor - retryRef: services-not-available-retry-strategy - retryableErrors: - - service-not-available - - name: schedule-appt - functionRef: schedule-appt - retryRef: services-not-available-retry-strategy - retryableErrors: - - service-not-available - onErrors: - - errorRef: service-not-available - end: true - end: true -events: - - name: store-patient - type: new.patients.event - source: newpatient/+ -functions: - - name: store-new-patient-info - operation: api/services.json#addPatient - - name: assign-doctor - operation: api/services.json#assignDoctor - - name: schedule-appt - operation: api/services.json#scheduleAppointment -errors: - - name: service-not-available - code: "503" -retries: - - name: services-not-available-retry-strategy - delay: PT3S - maxAttempts: 10 -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "order", - "name": "order", - "description": "Purchase Order Workflow", - "version": "1.0.0", - "specVersion": "0.8", - "start": "start-new-order", - "timeouts": { - "workflowExecTimeout": { - "duration": "PT30D", - "runBefore": "CancelOrder" - } - }, - "states": [ - { - "name": "start-new-order", - "type": "event", - "onEvents": [ - { - "eventRefs": [ - "order-created-event" - ], - "actions": [ - { - "name": "log-new-order-created", - "functionRef": { - "refName": "log-new-order-created" - } - } - ] - } - ], - "transition": { - "nextState": "wait-for-order-confirmation" - } - }, - { - "name": "wait-for-order-confirmation", - "type": "event", - "onEvents": [ - { - "eventRefs": [ - "order-confirmed-event" - ], - "actions": [ - { - "name": "log-order-confirmed", - "functionRef": { - "refName": "log-order-confirmed" - } - } - ] - } - ], - "transition": { - "nextState": "wait-order-shipped" - } - }, - { - "name": "wait-order-shipped", - "type": "event", - "onEvents": [ - { - "eventRefs": [ - "shipment-sent-event" - ], - "actions": [ - { - "name": "log-order-shipped", - "functionRef": { - "refName": "log-order-shipped" - } - } - ] - } - ], - "end": { - "terminate": true, - "produceEvents": [ - { - "eventRef": "order-finished-event" - } - ] - } - }, - { - "name": "cancel-order", - "type": "operation", - "actions": [ - { - "name": "cancel-order", - "functionRef": { - "refName": "cancel-order" - } - } - ], - "end": { - "terminate": true, - "produceEvents": [ - { - "eventRef": "order-cancelled-event" - } - ] - } - } - ], - "events": [ - { - "name": "order-created-event", - "type": "my.company.orders", - "source": "/orders/new", - "correlation": [ - { - "contextAttributeName": "orderid" - } - ] - }, - { - "name": "order-confirmed-event", - "type": "my.company.orders", - "source": "/orders/confirmed", - "correlation": [ - { - "contextAttributeName": "orderid" - } - ] - }, - { - "name": "shipment-sent-event", - "type": "my.company.orders", - "source": "/orders/shipped", - "correlation": [ - { - "contextAttributeName": "orderid" - } - ] - }, - { - "name": "order-finished-event", - "type": "my.company.orders", - "kind": "produced" - }, - { - "name": "order-cancelled-event", - "type": "my.company.orders", - "kind": "produced" - } - ], - "functions": [ - { - "name": "log-new-order-created", - "operation": "http.myorg.io/ordersservices.json#logcreated" - }, - { - "name": "log-order-confirmed", - "operation": "http.myorg.io/ordersservices.json#logconfirmed" - }, - { - "name": "log-order-shipped", - "operation": "http.myorg.io/ordersservices.json#logshipped" - }, - { - "name": "cancel-order", - "operation": "http.myorg.io/ordersservices.json#calcelorder" - } - ] -}``` - - | -- -```yaml -id: order -name: order -description: Purchase Order Workflow -version: 1.0.0 -specVersion: "0.8" -start: start-new-order -timeouts: - workflowExecTimeout: - duration: PT30D - runBefore: CancelOrder -states: - - name: start-new-order - type: event - onEvents: - - eventRefs: - - order-created-event - actions: - - name: log-new-order-created - functionRef: - refName: log-new-order-created - transition: - nextState: wait-for-order-confirmation - - name: wait-for-order-confirmation - type: event - onEvents: - - eventRefs: - - order-confirmed-event - actions: - - name: log-order-confirmed - functionRef: - refName: log-order-confirmed - transition: - nextState: wait-order-shipped - - name: wait-order-shipped - type: event - onEvents: - - eventRefs: - - shipment-sent-event - actions: - - name: log-order-shipped - functionRef: - refName: log-order-shipped - end: - terminate: true - produceEvents: - - eventRef: order-finished-event - - name: cancel-order - type: operation - actions: - - name: cancel-order - functionRef: - refName: cancel-order - end: - terminate: true - produceEvents: - - eventRef: order-cancelled-event -events: - - name: order-created-event - type: my.company.orders - source: /orders/new - correlation: - - contextAttributeName: orderid - - name: order-confirmed-event - type: my.company.orders - source: /orders/confirmed - correlation: - - contextAttributeName: orderid - - name: shipment-sent-event - type: my.company.orders - source: /orders/shipped - correlation: - - contextAttributeName: orderid - - name: order-finished-event - type: my.company.orders - kind: produced - - name: order-cancelled-event - type: my.company.orders - kind: produced -functions: - - name: log-new-order-created - operation: http.myorg.io/ordersservices.json#logcreated - - name: log-order-confirmed - operation: http.myorg.io/ordersservices.json#logconfirmed - - name: log-order-shipped - operation: http.myorg.io/ordersservices.json#logshipped - - name: cancel-order - operation: http.myorg.io/ordersservices.json#calcelorder -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "roomreadings", - "name": "roomreadings", - "description": "Room Temp and Humidity Workflow", - "version": "1.0.0", - "specVersion": "0.8", - "start": "consume-reading", - "timeouts": { - "workflowExecTimeout": { - "duration": "PT1H", - "runBefore": "generate-report" - } - }, - "keepActive": true, - "states": [ - { - "name": "consume-reading", - "type": "event", - "onEvents": [ - { - "eventRefs": [ - "temperature-event", - "humidity-event" - ], - "actions": [ - { - "name": "log-reading", - "functionRef": { - "refName": "log-reading" - } - } - ], - "eventDataFilter": { - "toStateData": "${ .readings }" - } - } - ], - "end": true - }, - { - "name": "generate-report", - "type": "operation", - "actions": [ - { - "name": "generate-report", - "functionRef": { - "refName": "produce-report", - "arguments": { - "data": "${ .readings }" - } - } - } - ], - "end": { - "terminate": true - } - } - ], - "events": [ - { - "name": "temperature-event", - "type": "my.home.sensors", - "source": "/home/rooms/+", - "correlation": [ - { - "contextAttributeName": "roomId" - } - ] - }, - { - "name": "humidity-event", - "type": "my.home.sensors", - "source": "/home/rooms/+", - "correlation": [ - { - "contextAttributeName": "roomId" - } - ] - } - ], - "functions": [ - { - "name": "log-reading", - "operation": "http.myorg.io/ordersservices.json#logreading" - }, - { - "name": "produce-report", - "operation": "http.myorg.io/ordersservices.json#produceReport" - } - ] -}``` - - | -- -```yaml -id: roomreadings -name: roomreadings -description: Room Temp and Humidity Workflow -version: 1.0.0 -specVersion: "0.8" -start: consume-reading -timeouts: - workflowExecTimeout: - duration: PT1H - runBefore: generate-report -keepActive: true -states: - - name: consume-reading - type: event - onEvents: - - eventRefs: - - temperature-event - - humidity-event - actions: - - name: log-reading - functionRef: - refName: log-reading - eventDataFilter: - toStateData: ${ .readings } - end: true - - name: generate-report - type: operation - actions: - - name: generate-report - functionRef: - refName: produce-report - arguments: - data: ${ .readings } - end: - terminate: true -events: - - name: temperature-event - type: my.home.sensors - source: /home/rooms/+ - correlation: - - contextAttributeName: roomId - - name: humidity-event - type: my.home.sensors - source: /home/rooms/+ - correlation: - - contextAttributeName: roomId -functions: - - name: log-reading - operation: http.myorg.io/ordersservices.json#logreading - - name: produce-report - operation: http.myorg.io/ordersservices.json#produceReport -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "checkcarvitals", - "name": "checkcarvitals", - "description": "Check Car Vitals Workflow", - "version": "1.0.0", - "specVersion": "0.8", - "start": "when-car-is-on", - "states": [ - { - "name": "when-car-is-on", - "type": "event", - "onEvents": [ - { - "eventRefs": [ - "car-turned-on-event" - ] - } - ], - "transition": "do-car-vital-checks" - }, - { - "name": "do-car-vital-checks", - "type": "operation", - "actions": [ - { - "name": "do-car-vital-checks", - "subFlowRef": "vitalscheck", - "sleep": { - "after": "PT1S" - } - } - ], - "transition": "check-continue-vital-checks" - }, - { - "name": "check-continue-vital-checks", - "type": "switch", - "eventConditions": [ - { - "name": "car-turned-off-condition", - "eventRef": "car-turned-off-event", - "end": true - } - ], - "defaultCondition": { - "transition": "do-car-vital-checks" - } - } - ], - "events": [ - { - "name": "car-turned-on-event", - "type": "car.events", - "source": "my/car" - }, - { - "name": "car-turned-off-event", - "type": "car.events", - "source": "my/car" - } - ] -}``` - - | -- -```yaml -id: checkcarvitals -name: checkcarvitals -description: Check Car Vitals Workflow -version: 1.0.0 -specVersion: "0.8" -start: when-car-is-on -states: - - name: when-car-is-on - type: event - onEvents: - - eventRefs: - - car-turned-on-event - transition: do-car-vital-checks - - name: do-car-vital-checks - type: operation - actions: - - name: do-car-vital-checks - subFlowRef: vitalscheck - sleep: - after: PT1S - transition: check-continue-vital-checks - - name: check-continue-vital-checks - type: switch - eventConditions: - - name: car-turned-off-condition - eventRef: car-turned-off-event - end: true - defaultCondition: - transition: do-car-vital-checks -events: - - name: car-turned-on-event - type: car.events - source: my/car - - name: car-turned-off-event - type: car.events - source: my/car -``` - - | -
JSON | -YAML | -|
---|---|---|
- -```json -{ - "id": "vitalscheck", - "name": "vitalscheck", - "description": "Car Vitals Check", - "version": "1.0.0", - "specVersion": "0.8", - "start": "check-vitals", - "states": [ - { - "name": "check-vitals", - "type": "operation", - "actions": [ - { - "name": "check-tire-pressure", - "functionRef": "check-tire-pressure" - }, - { - "name": "check-oil-pressure", - "functionRef": "check-oil-pressure" - }, - { - "name": "check-coolant-level", - "functionRef": "check-coolant-level" - }, - { - "name": "check-battery", - "functionRef": "check-battery" - } - ], - "end": { - "produceEvents": [ - { - "eventRef": "display-checks-on-dashboard", - "data": "${ .evaluations }" - } - ] - } - } - ], - "functions": [ - { - "name": "check-tire-pressure", - "operation": "mycarservices.json#checktirepressure" - }, - { - "name": "check-oil-pressure", - "operation": "mycarservices.json#checkoilpressure" - }, - { - "name": "check-coolant-level", - "operation": "mycarservices.json#checkcoolantlevel" - }, - { - "name": "check-battery", - "operation": "mycarservices.json#checkbattery" - } - ] -}``` - - | -- -```yaml -id: vitalscheck -name: vitalscheck -description: Car Vitals Check -version: 1.0.0 -specVersion: "0.8" -start: check-vitals -states: - - name: check-vitals - type: operation - actions: - - name: check-tire-pressure - functionRef: check-tire-pressure - - name: check-oil-pressure - functionRef: check-oil-pressure - - name: check-coolant-level - functionRef: check-coolant-level - - name: check-battery - functionRef: check-battery - end: - produceEvents: - - eventRef: display-checks-on-dashboard - data: ${ .evaluations } -functions: - - name: check-tire-pressure - operation: mycarservices.json#checktirepressure - - name: check-oil-pressure - operation: mycarservices.json#checkoilpressure - - name: check-coolant-level - operation: mycarservices.json#checkcoolantlevel - - name: check-battery - operation: mycarservices.json#checkbattery -``` - - | -- -```yaml -id: vitalscheck -name: Car Vitals Check -version: '1.0.0' -specVersion: '0.8' -start: CheckVitals -states: - - name: CheckVitals - type: operation - actions: - - functionRef: Check Tire Pressure - - functionRef: Check Oil Pressure - - functionRef: Check Coolant Level - - functionRef: Check Battery - end: - produceEvents: - - eventRef: DisplayChecksOnDashboard - data: "${ .evaluations }" -functions: - - name: checkTirePressure - operation: mycarservices.json#checktirepressure - - name: checkOilPressure - operation: mycarservices.json#checkoilpressure - - name: checkCoolantLevel - operation: mycarservices.json#checkcoolantlevel - - name: checkBattery - operation: mycarservices.json#checkbattery -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "booklending", - "name": "booklending", - "description": "Book Lending Workflow", - "version": "1.0.0", - "specVersion": "0.8", - "start": "book-lending-request", - "states": [ - { - "name": "book-lending-request", - "type": "event", - "onEvents": [ - { - "eventRefs": [ - "book-lending-request-event" - ] - } - ], - "transition": "get-book-status" - }, - { - "name": "get-book-status", - "type": "operation", - "actions": [ - { - "name": "get-book-status", - "functionRef": { - "refName": "get-status-for-book", - "arguments": { - "bookid": "${ .book.id }" - } - } - } - ], - "transition": "book-status-decision" - }, - { - "name": "book-status-decision", - "type": "switch", - "dataConditions": [ - { - "name": "book-is-on-loan", - "condition": "${ .book.status == \"onloan\" }", - "transition": "report-status-to-lender" - }, - { - "name": "check-is-available", - "condition": "${ .book.status == \"available\" }", - "transition": "check-out-book" - } - ], - "defaultCondition": { - "end": true - } - }, - { - "name": "report-status-to-lender", - "type": "operation", - "actions": [ - { - "name": "report-status-to-lender", - "functionRef": { - "refName": "send-status-to-lender", - "arguments": { - "bookid": "${ .book.id }", - "message": "Book ${ .book.title } is already on loan" - } - } - } - ], - "transition": "wait-for-lender-response" - }, - { - "name": "wait-for-lender-response", - "type": "switch", - "eventConditions": [ - { - "name": "hold-book", - "eventRef": "hold-book-event", - "transition": "request-hold" - }, - { - "name": "decline-book-hold", - "eventRef": "decline-hold-event", - "transition": "cancel-request" - } - ], - "defaultCondition": { - "end": true - } - }, - { - "name": "request-hold", - "type": "operation", - "actions": [ - { - "name": "request-hold", - "functionRef": { - "refName": "request-hold-for-lender", - "arguments": { - "bookid": "${ .book.id }", - "lender": "${ .lender }" - } - } - } - ], - "transition": "sleep-two-weeks" - }, - { - "name": "cancel-request", - "type": "operation", - "actions": [ - { - "name": "cancel-request", - "functionRef": { - "refName": "cancel-hold-request-for-lender", - "arguments": { - "bookid": "${ .book.id }", - "lender": "${ .lender }" - } - } - } - ], - "transition": "sleep-two-weeks" - }, - { - "name": "sleep-two-weeks", - "type": "sleep", - "duration": "PT2W", - "transition": "get-book-status" - }, - { - "name": "check-out-book", - "type": "operation", - "actions": [ - { - "name": "check-out-book", - "functionRef": { - "refName": "check-out-book-with-id", - "arguments": { - "bookid": "${ .book.id }" - } - } - }, - { - "name": "notify-lender-for-checkout", - "functionRef": { - "refName": "notify-lender-for-checkout", - "arguments": { - "bookid": "${ .book.id }", - "lender": "${ .lender }" - } - } - } - ], - "end": true - } - ], - "functions": "file://books/lending/functions.json", - "events": "file://books/lending/events.json" -}``` - - | -- -```yaml -id: booklending -name: booklending -description: Book Lending Workflow -version: 1.0.0 -specVersion: "0.8" -start: book-lending-request -states: - - name: book-lending-request - type: event - onEvents: - - eventRefs: - - book-lending-request-event - transition: get-book-status - - name: get-book-status - type: operation - actions: - - name: get-book-status - functionRef: - refName: get-status-for-book - arguments: - bookid: ${ .book.id } - transition: book-status-decision - - name: book-status-decision - type: switch - dataConditions: - - name: book-is-on-loan - condition: ${ .book.status == "onloan" } - transition: report-status-to-lender - - name: check-is-available - condition: ${ .book.status == "available" } - transition: check-out-book - defaultCondition: - end: true - - name: report-status-to-lender - type: operation - actions: - - name: report-status-to-lender - functionRef: - refName: send-status-to-lender - arguments: - bookid: ${ .book.id } - message: Book ${ .book.title } is already on loan - transition: wait-for-lender-response - - name: wait-for-lender-response - type: switch - eventConditions: - - name: hold-book - eventRef: hold-book-event - transition: request-hold - - name: decline-book-hold - eventRef: decline-hold-event - transition: cancel-request - defaultCondition: - end: true - - name: request-hold - type: operation - actions: - - name: request-hold - functionRef: - refName: request-hold-for-lender - arguments: - bookid: ${ .book.id } - lender: ${ .lender } - transition: sleep-two-weeks - - name: cancel-request - type: operation - actions: - - name: cancel-request - functionRef: - refName: cancel-hold-request-for-lender - arguments: - bookid: ${ .book.id } - lender: ${ .lender } - transition: sleep-two-weeks - - name: sleep-two-weeks - type: sleep - duration: PT2W - transition: get-book-status - - name: check-out-book - type: operation - actions: - - name: check-out-book - functionRef: - refName: check-out-book-with-id - arguments: - bookid: ${ .book.id } - - name: notify-lender-for-checkout - functionRef: - refName: notify-lender-for-checkout - arguments: - bookid: ${ .book.id } - lender: ${ .lender } - end: true -functions: file://books/lending/functions.json -events: file://books/lending/events.json -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "fillglassofwater", - "name": "fillglassofwater", - "description": "Fill glass of water workflow", - "version": "1.0.0", - "specVersion": "0.8", - "start": "check-if-full", - "functions": [ - { - "name": "increment-current-count-function", - "type": "expression", - "operation": ".counts.current += 1 | .counts.current" - } - ], - "states": [ - { - "name": "check-if-full", - "type": "switch", - "dataConditions": [ - { - "name": "need-to-fill-more", - "condition": "${ .counts.current < .counts.max }", - "transition": "add-water" - }, - { - "name": "glass-full", - "condition": ".counts.current >= .counts.max", - "end": true - } - ], - "defaultCondition": { - "end": true - } - }, - { - "name": "add-water", - "type": "operation", - "actions": [ - { - "name": "add-water", - "functionRef": "increment-current-count-function", - "actionDataFilter": { - "toStateData": ".counts.current" - } - } - ], - "transition": "check-if-full" - } - ] -}``` - - | -- -```yaml -id: fillglassofwater -name: fillglassofwater -description: Fill glass of water workflow -version: 1.0.0 -specVersion: "0.8" -start: check-if-full -functions: - - name: increment-current-count-function - type: expression - operation: .counts.current += 1 | .counts.current -states: - - name: check-if-full - type: switch - dataConditions: - - name: need-to-fill-more - condition: ${ .counts.current < .counts.max } - transition: add-water - - name: glass-full - condition: .counts.current >= .counts.max - end: true - defaultCondition: - end: true - - name: add-water - type: operation - actions: - - name: add-water - functionRef: increment-current-count-function - actionDataFilter: - toStateData: .counts.current - transition: check-if-full -``` - - | -
-
-
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "notifycustomerworkflow", - "name": "notifycustomerworkflow", - "description": "Notify Customer", - "version": "1.0.0", - "specVersion": "0.8", - "start": "wait-for-customer-event", - "states": [ - { - "name": "wait-for-customer-event", - "type": "event", - "onEvents": [ - { - "eventRefs": [ - "customer-event" - ], - "eventDataFilter": { - "data": "${ .customerId }", - "toStateData": "${ .eventCustomerId }" - }, - "actions": [ - { - "name": "notify-customer-function", - "functionRef": { - "refName": "notify-customer-function", - "arguments": { - "customerId": "${ .eventCustomerId }" - } - } - } - ] - } - ], - "stateDataFilter": { - "output": "${ .count = .count + 1 }" - }, - "transition": "check-event-quota" - }, - { - "name": "check-event-quota", - "type": "switch", - "dataConditions": [ - { - "name": "ready", - "condition": "${ try(.customerCount) != null and .customerCount > .quota.maxConsumedEvents }", - "end": { - "continueAs": { - "workflowId": "notifycustomerworkflow", - "version": "1.0.0", - "data": "${ del(.customerCount) }" - } - } - } - ], - "defaultCondition": { - "transition": "wait-for-customer-event" - } - } - ], - "events": [ - { - "name": "customer-event", - "type": "org.events.customerEvent", - "source": "customerSource" - } - ], - "functions": [ - { - "name": "notify-customer-function", - "operation": "http://myapis.org/customerapis.json#notifyCustomer" - } - ] -}``` - - | -- -```yaml -id: notifycustomerworkflow -name: notifycustomerworkflow -description: Notify Customer -version: 1.0.0 -specVersion: "0.8" -start: wait-for-customer-event -states: - - name: wait-for-customer-event - type: event - onEvents: - - eventRefs: - - customer-event - eventDataFilter: - data: ${ .customerId } - toStateData: ${ .eventCustomerId } - actions: - - name: notify-customer-function - functionRef: - refName: notify-customer-function - arguments: - customerId: ${ .eventCustomerId } - stateDataFilter: - output: ${ .count = .count + 1 } - transition: check-event-quota - - name: check-event-quota - type: switch - dataConditions: - - name: ready - condition: ${ try(.customerCount) != null and .customerCount > - .quota.maxConsumedEvents } - end: - continueAs: - workflowId: notifycustomerworkflow - version: 1.0.0 - data: ${ del(.customerCount) } - defaultCondition: - transition: wait-for-customer-event -events: - - name: customer-event - type: org.events.customerEvent - source: customerSource -functions: - - name: notify-customer-function - operation: http://myapis.org/customerapis.json#notifyCustomer -``` - - | -
JSON | -YAML | -
---|---|
- -```json -{ - "id": "customerbankingtransactions", - "name": "customerbankingtransactions", - "description": "Customer Banking Transactions Workflow", - "version": "1.0.0", - "specVersion": "0.8", - "autoRetries": true, - "constants": { - "largetxamount": 5000 - }, - "states": [ - { - "name": "process-transactions", - "type": "foreach", - "inputCollection": "${ .customer.transactions }", - "iterationParam": "${ .tx }", - "actions": [ - { - "name": "process-larger-transaction", - "functionRef": "banking-service-larger-tx", - "condition": "${ .tx >= $CONST.largetxamount }" - }, - { - "name": "process-smaller-transaction", - "functionRef": "banking-service-smaller-tx", - "condition": "${ .tx < $CONST.largetxamount }" - } - ], - "end": true - } - ], - "functions": [ - { - "name": "banking-service-larger-tx", - "type": "asyncapi", - "operation": "banking.yaml#largerTransation" - }, - { - "name": "banking-service-smaller-tx", - "type": "asyncapi", - "operation": "banking.yaml#smallerTransation" - } - ] -}``` - - | -- -```yaml -id: customerbankingtransactions -name: customerbankingtransactions -description: Customer Banking Transactions Workflow -version: 1.0.0 -specVersion: "0.8" -autoRetries: true -constants: - largetxamount: 5000 -states: - - name: process-transactions - type: foreach - inputCollection: ${ .customer.transactions } - iterationParam: ${ .tx } - actions: - - name: process-larger-transaction - functionRef: banking-service-larger-tx - condition: ${ .tx >= $CONST.largetxamount } - - name: process-smaller-transaction - functionRef: banking-service-smaller-tx - condition: ${ .tx < $CONST.largetxamount } - end: true -functions: - - name: banking-service-larger-tx - type: asyncapi - operation: banking.yaml#largerTransation - - name: banking-service-smaller-tx - type: asyncapi - operation: banking.yaml#smallerTransation -``` - - | -
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
JSON | -YAML | -|
---|---|---|
-
-```json
- |
-
-
-```yaml
- |
-- -```yaml -id: vitalscheck -name: Car Vitals Check -version: '1.0.0' -specVersion: '0.8' -start: CheckVitals -states: - - name: CheckVitals - type: operation - actions: - - functionRef: Check Tire Pressure - - functionRef: Check Oil Pressure - - functionRef: Check Coolant Level - - functionRef: Check Battery - end: - produceEvents: - - eventRef: DisplayChecksOnDashboard - data: "${ .evaluations }" -functions: - - name: checkTirePressure - operation: mycarservices.json#checktirepressure - - name: checkOilPressure - operation: mycarservices.json#checkoilpressure - - name: checkCoolantLevel - operation: mycarservices.json#checkcoolantlevel - - name: checkBattery - operation: mycarservices.json#checkbattery -``` - - | -
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
Workflow | -KPIs Extension | -
---|---|
- -```yaml -id: patientVitalsWorkflow -name: Monitor Patient Vitals -version: '1.0.0' -specVersion: '0.8' -start: MonitorVitals -extensions: - - extensionId: workflow-kpi-extension - path: file://myextensions/kpi.yml -events: - - name: HighBodyTemperature - type: org.monitor.highBodyTemp - source: monitoringSource - correlation: - - contextAttributeName: patientId - - name: HighBloodPressure - type: org.monitor.highBloodPressure - source: monitoringSource - correlation: - - contextAttributeName: patientId - - name: HighRespirationRate - type: org.monitor.highRespirationRate - source: monitoringSource - correlation: - - contextAttributeName: patientId -functions: - - name: callPulmonologist - operation: http://myapi.org/patientapi.json#callPulmonologist - - name: sendTylenolOrder - operation: http://myapi.org/patientapi.json#sendTylenol - - name: callNurse - operation: http://myapi.org/patientapi.json#callNurse -states: - - name: MonitorVitals - type: event - exclusive: true - onEvents: - - eventRefs: - - HighBodyTemperature - actions: - - functionRef: - refName: sendTylenolOrder - arguments: - patientid: "${ .patientId }" - - eventRefs: - - HighBloodPressure - actions: - - functionRef: - refName: callNurse - arguments: - patientid: "${ .patientId }" - - eventRefs: - - HighRespirationRate - actions: - - functionRef: - refName: callPulmonologist - arguments: - patientid: "${ .patientId }" - end: true -``` - - | -- -```yaml -extensionid: workflow-kpi-extension -currency: USD -workflow: - per: - time: PT1D - maxCost: '1300' - maxInvoked: '500' - minInvoked: '100' -events: -- for: HighBodyTemperature - per: - time: PT1D - avgConsumed: '50' -- for: HighBloodPressure - per: - time: PT1D - avgConsumed: '30' -functions: -- for: callPulmonologist - per: - instances: 1000 - maxCost: '400' - maxErrors: '5' - maxRetry: '10' - maxTimeout: '15' - avgInvoked: '40' -- for: sendTylenolOrder - per: - instances: 1000 - maxCost: '200' - maxErrors: '5' - maxRetry: '10' - maxTimeout: '15' - avgInvoked: '400' -states: -- for: MonitorVitals - per: - time: PT1D - maxCost: '300' - maxExec: '1000' - minExec: '50' -``` - - | -
Workflow | -Rate Limiting Extension | -
---|---|
- -```yaml -id: processapplication -name: Process Application -version: '1.0.0' -specVersion: '0.8' -extensions: - - extensionId: workflow-ratelimiting-extension - path: file://myextensions/ratelimiting.yml -start: ProcessNewApplication -states: - - name: ProcessNewApplication - type: event - onEvents: - - eventRefs: - - ApplicationReceivedEvent - actions: - - functionRef: processApplicationFunction - - functionRef: acceptApplicantFunction - - functionRef: depositFeesFunction - end: - produceEvents: - - eventRef: NotifyApplicantEvent -functions: - - name: processApplicationFunction - operation: file://myservice.json#process - - name: acceptApplicantFunction - operation: file://myservice.json#accept - - name: depositFeesFunction - operation: file://myservice.json#deposit -events: - - name: ApplicationReceivedEvent - type: application - source: "/applications/new" - - name: NotifyApplicantEvent - type: notifications - source: "/applicants/notify" -``` - - | -- -```yaml -extensionid: workflow-ratelimiting-extension -singleInstance: - maxActionsPerSecond: 0.1 - maxConcurrentActions: 200 - maxProducedEventsPerSecond: 2 - maxStates: '1000' - maxTransitions: '1000' -allInstances: - maxActionsPerSecond: 1 - maxConcurrentActions: 500 - maxProducedEventsPerSecond: 20 - maxStates: '10000' - maxTransitions: '10000' - -``` - - | -
-
-
-
-
-
-
-
-
-
-
-
-
- -
JSON | -YAML | -
---|---|
- -```json -{ - "stateDataFilter": { - "input": "${ .orders }", - "output": "${ .provisionedOrders }" - } -} -``` - - | -- -```yaml -stateDataFilter: - input: "${ .orders }" - output: "${ .provisionedOrders }" -``` - - | -
-
-
-
-
- -
JSON | -YAML | -
---|---|
- -```json -{ - "actionDataFilter": { - "fromStateData": "${ .language }", - "results": "${ .results.greeting }", - "toStateData": "${ .finalgreeting }" - } -} -``` - - | -- -```yaml -actionDataFilter: - fromStateData: "${ .language }" - results: "${ .results.greeting }" - toStateData: "${ .finalgreeting }" -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "eventDataFilter": { - "data": "${ .data.results }" - } -} -``` - - | -- -```yaml -eventDataFilter: - data: "${ .data.results }" -``` - - | -
-
-
-
-
- -
JSON | -YAML | -
---|---|
- -```json -{ - "name": "sample-workflow", - "version": "1.0.0", - "specVersion": "0.8", - "description": "Sample Workflow", - "start": "MyStartingState", - "states": [], - "functions": [], - "events": [], - "errors": [], - "retries":[] -} -``` - - | -- -```yaml -name: sample-workflow -version: '1.0.0' -specVersion: '0.8' -description: Sample Workflow -start: MyStartingState -states: [] -functions: [] -events: [] -errors: [] -retries: [] -``` - - | -
-
-
- -
JSON | -YAML | -
---|---|
- -```json -{ -"name": "monitor-vitals", -"type": "event", -"exclusive": true, -"onEvents": [{ - "eventRefs": ["high-body-temperature"], - "actions": [{ - "functionRef": { - "refName": "send-tylenol-order", - "arguments": { - "patientid": "${ .patientId }" - } - } - }] - }, - { - "eventRefs": ["high-blood-pressure"], - "actions": [{ - "functionRef": { - "refName": "call-nurse", - "arguments": { - "patientid": "${ .patientId }" - } - } - }] - }, - { - "eventRefs": ["high-respiration-rate"], - "actions": [{ - "functionRef": { - "refName": "call-pulmonologist", - "arguments": { - "patientid": "${ .patientId }" - } - } - }] - } -], -"end": { - "terminate": true -} -} -``` - - | -- -```yaml -name: monitor-vitals -type: event -exclusive: true -onEvents: -- eventRefs: - - high-body-temperature - actions: - - functionRef: - refName: send-tylenol-order - arguments: - patientid: "${ .patientId }" -- eventRefs: - - high-blood-pressure - actions: - - functionRef: - refName: call-nurse - arguments: - patientid: "${ .patientId }" -- eventRefs: - - high-respiration-rate - actions: - - functionRef: - refName: call-pulmonologist - arguments: - patientid: "${ .patientId }" -end: - terminate: true -``` - - | -
-
-
-
-
- -
JSON | -YAML | -
---|---|
- -```json -{ - "name": "reject-application", - "type": "operation", - "actionMode": "sequential", - "actions": [ - { - "functionRef": { - "refName": "send-rejection-email-function", - "arguments": { - "customer": "${ .customer }" - } - } - } - ], - "end": true -} -``` - - | -- -```yaml -name: reject-application -type: operation -actionMode: sequential -actions: -- functionRef: - refName: send-rejection-email-function - arguments: - customer: "${ .customer }" -end: true -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "name":"check-visa-status", - "type":"switch", - "eventConditions": [ - { - "eventRef": "visa-approved-event", - "transition": "handle-approved-visa" - }, - { - "eventRef": "visa-rejected-event", - "transition": "handle-rejected-visa" - } - ], - "timeouts": { - "eventTimeout": "PT1H" - }, - "defaultCondition": { - "transition": "handle-no-visa-decision" - } -} -``` - - | -- -```yaml -name: check-visa-status -type: switch -eventConditions: -- eventRef: visa-approved-event - transition: handle-approved-visa -- eventRef: visa-rejected-event - transition: handle-rejected-visa -timeouts: - eventTimeout: PT1H -defaultCondition: - transition: handle-no-visa-decision -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json - { - "name":"parallel-exec", - "type":"parallel", - "completionType": "allOf", - "branches": [ - { - "name": "branch-1", - "actions": [ - { - "functionRef": { - "refName": "function-name-one", - "arguments": { - "order": "${ .someParam }" - } - } - } - ] - }, - { - "name": "branch-2", - "actions": [ - { - "functionRef": { - "refName": "function-name-two", - "arguments": { - "order": "${ .someParam }" - } - } - } - ] - } - ], - "end": true -} -``` - - | -- -```yaml -name: parallel-exec -type: parallel -completionType: allOf -branches: -- name: branch-1 - actions: - - functionRef: - refName: function-name-one - arguments: - order: "${ .someParam }" -- name: branch-2 - actions: - - functionRef: - refName: function-name-two - arguments: - order: "${ .someParam }" -end: true -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "name":"hello", - "type":"inject", - "data": { - "result": "Hello" - }, - "transition": "world" -} -``` - - | -- -```yaml -name: hello -type: inject -data: - result: Hello -transition: world -``` - - | -
JSON | -YAML | -
---|---|
- - ```json - { - "name":"simple-inject-state", - "type":"inject", - "data": { - "person": { - "fname": "John", - "lname": "Doe", - "address": "1234 SomeStreet", - "age": 40 - } - }, - "transition": "greet-person-state" - } - ``` - - | -- -```yaml - name: simple-inject-state - type: inject - data: - person: - fname: John - lname: Doe - address: 1234 SomeStreet - age: 40 - transition: greet-person-state -``` - - | -
JSON | -YAML | -
---|---|
- -```json - { - "name":"simple-inject-state", - "type":"inject", - "data": { - "people": [ - { - "fname": "John", - "lname": "Doe", - "address": "1234 SomeStreet", - "age": 40 - }, - { - "fname": "Marry", - "lname": "Allice", - "address": "1234 SomeStreet", - "age": 25 - }, - { - "fname": "Kelly", - "lname": "Mill", - "address": "1234 SomeStreet", - "age": 30 - } - ] - }, - "stateDataFilter": { - "output": "${ {people: [.people[] | select(.age < 40)]} }" - }, - "transition": "greet-person-state" - } -``` - - | -- -```yaml - name: simple-inject-state - type: inject - data: - people: - - fname: John - lname: Doe - address: 1234 SomeStreet - age: 40 - - fname: Marry - lname: Allice - address: 1234 SomeStreet - age: 25 - - fname: Kelly - lname: Mill - address: 1234 SomeStreet - age: 30 - stateDataFilter: - output: "${ {people: [.people[] | select(.age < 40)]} }" - transition: greet-person-state -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "name": "provision-orders-state", - "type": "foreach", - "inputCollection": "${ .orders }", - "iterationParam": "singleorder", - "outputCollection": "${ .provisionresults }", - "actions": [ - { - "functionRef": { - "refName": "provision-order-function", - "arguments": { - "order": "${ $singleorder }" - } - } - } - ] -} -``` - - | -- -```yaml -name: provision-orders-state -type: foreach -inputCollection: "${ .orders }" -iterationParam: "singleorder" -outputCollection: "${ .provisionresults }" -actions: -- functionRef: - refName: provision-order-function - arguments: - order: "${ $singleorder }" -``` - - | -
JSON | -YAML | -
---|---|
- -```json -{ - "name": "send-confirmation-for-completed-orders", - "version": "1.0.0", - "specVersion": "0.8", - "start": "send-confirm-state", - "functions": [ - { - "name": "send-confirmation-function", - "operation": "file://confirmationapi.json#sendOrderConfirmation" - } - ], - "states": [ - { - "name":"send-confirm-state", - "type":"foreach", - "inputCollection": "${ [.orders[] | select(.completed == true)] }", - "iterationParam": "completedorder", - "outputCollection": "${ .confirmationresults }", - "actions":[ - { - "functionRef": { - "refName": "send-confirmation-function", - "arguments": { - "orderNumber": "${ $completedorder.orderNumber }", - "email": "${ $completedorder.email }" - } - } - }], - "end": true - }] -} -``` - - | -- -```yaml -name: send-confirmation-for-completed-orders -version: '1.0.0' -specVersion: '0.8' -start: send-confirm-state -functions: -- name: send-confirmation-function - operation: file://confirmationapi.json#sendOrderConfirmation -states: -- name: send-confirm-state - type: foreach - inputCollection: "${ [.orders[] | select(.completed == true)] }" - iterationParam: completedorder - outputCollection: "${ .confirmationresults }" - actions: - - functionRef: - refName: send-confirmation-function - arguments: - orderNumber: "${ $completedorder.orderNumber }" - email: "${ $completedorder.email }" - end: true -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "name": "check-credit", - "type": "callback", - "action": { - "functionRef": { - "refName": "call-credit-check-microservice", - "arguments": { - "customer": "${ .customer }" - } - } - }, - "eventRef": "credit-check-completed-event", - "timeouts": { - "stateExecTimeout": "PT15M" - }, - "transition": "evaluate-decision" -} -``` - - | -- -```yaml -name: check-credit -type: callback -action: - functionRef: - refName: call-credit-check-microservice - arguments: - customer: "${ .customer }" -eventRef: credit-check-completed-event -timeouts: - stateExecTimeout: PT15M -transition: evaluate-decision -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "name": "hello-world-function", - "operation": "https://hellworldservice.api.com/api.json#helloWorld" -} -``` - - | -- -```yaml -name: hello-world-function -operation: https://hellworldservice.api.com/api.json#helloWorld -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "name": "applicant-info", - "type": "org.application.info", - "source": "applicationssource", - "correlation": [ - { - "contextAttributeName": "applicantId" - } - ] -} -``` - - | -- -```yaml -name: applicant-info -type: org.application.info -source: applicationssource -correlation: -- contextAttributeName: applicantId -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "correlation": [ - { - "contextAttributeName": "patientId" - }, - { - "contextAttributeName": "department", - "contextAttributeValue" : "UrgentCare" - } - ] -} -``` - - | -- -```yaml -correlation: -- contextAttributeName: patientId -- contextAttributeName: department - contextAttributeValue: UrgentCare -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "eventRefs": ["high-body-temperature"], - "actions": [{ - "functionRef": { - "refName": "send-tylenol-order", - "arguments": { - "patientid": "${ .patientId }" - } - } - }] -} -``` - - | -- -```yaml -eventRefs: -- high-body-temperature -actions: -- functionRef: - refName: send-tylenol-order - arguments: - patientid: "${ .patientId }" -``` - - | -
-
-
- -
JSON | -YAML | -
---|---|
- -```json -{ - "name": "finalize-application-action", - "functionRef": { - "refName": "finalize-application-function", - "arguments": { - "applicantid": "${ .applicantId }" - } - } -} -``` - - | -- -```yaml -name: finalize-application-action -functionRef: - refName: finalize-application-function - arguments: - applicantid: "${ .applicantId }" -``` - - | -
-
-
- -
JSON | -YAML | -
---|---|
- -```json -{ - "refName": "finalize-application-function", - "arguments": { - "applicantid": "${ .applicantId }" - } -} -``` - - | -- -```yaml -refName: finalize-application-function -arguments: - applicantid: "${ .applicantId }" -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "publish": { - "event": "make-vet-appointment", - "data": "${ .patientInfo }", - } -} -``` - - | -- -```yaml -publish: - event: make-vet-appointment - data: "${ .patientInfo }" -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "subscribe": { - "name": "approved-appointment", - } -} -``` - - | -- -```yaml -eventRef: - subscribe: approved-appointment - -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "workflowId": "handle-approved-visa", - "version": "2.0.0" -} -``` - - | -- -```yaml -workflowId: handle-approved-visa -version: '2.0.0' -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "retries": [ - { - "name": "retry-five-times", - "maxAttempts": 5 - } - ], - "errors": { - "definitions": [ - { - "name": "service-not-available-error", - "type": "https://serverlessworkflow.io/spec/errors/communication", - "status": 503, - "title": "Service Not Available", - "detail": "Failed to contact service, even after multiple retries" - } - ], - "handlers": [ - { - "name": "handle-503", - "when": [ - { - "status": 503 - } - ], - "retry": "retry-five-times", - "then": { - "throw": { - "refName": "service-not-available-error" - } - } - } - ], - "policies": [ - { - "name": "fault-tolerance-policy", - "handlers": [ - { - "refName": "handle-503" - } - ] - } - ] - } -} -``` - - | -- -```yaml -retries: - - name: retry-five-times - maxAttempts: 5 -errors: - definitions: - - name: service-not-available-error - type: https://serverlessworkflow.io/spec/errors/communication - status: 503 - title: Service Not Available - detail: Failed to contact service, even after multiple retries - handlers: - - name: handle-503 - when: - - status: 503 - retry: retry-five-times - then: - throw: - refName: service-not-available-error - policies: - - name: fault-tolerance-policy - handlers: - - refName: handle-503 -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "instance": "/states/0/actions/0", - "type": "https://example.com/errors#timeout", - "status": 504, - "title": "Function Timeout", - "detail": "The function 'my-function' timed out." -} -``` - - | -- -```yaml -instance: "/states/0/actions/0" -type: "https://example.com/errors#timeout" -status: 504 -title: "Function Timeout" -detail: "The function 'my-function' timed out." -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "type": "https://example.com/errors#timeout", - "status": 504 -} -``` - - | -- -```yaml -type: "https://example.com/errors#timeout" -status: 504 -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "errors": { - "handlers": [ - { - "name": "handle-invalid-error", - "when": [ - { "error": "invalid" }, - { "status": 404 }, - { "status": 403 } - ], - "then": { - "transition": "my-state" - } - }, - { - "name": "handle-timeout-error", - "when": [ - { "status": 503 } - ], - "retry": "my-retry-policy", - "then": { - "transition": "my-state" - } - } - ] - } -} -``` - - | -- -```yaml -errors: - handlers: - - name: 'handle-invalid-error' - when: - - type: 'invalid' - - status: 404 - - status: 403 - then: - transition: 'my-state' - - name: 'handle-timeout-error' - when: - - status: 503 - retry: 'my-retry-policy' - then: - transition: 'my-state' -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "errors": { - "policies": [ - { - "name": "my-retry-policy", - "handlers": [ - { - "refName": "handle-timeout-error" - }, - { - "when": [ - { "status": 503 } - ], - "retry": "my-retry-policy" - } - ] - } - ] - } -} -``` - - | -- -```yaml -errors: - policies: - - name: 'my-retry-policy' - handlers: - - refName: 'handle-timeout-error' - - when: - - status: 503 - retry: 'my-retry-policy' -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "errors": { - "policies": [ - { - "name": "my-retry-policy", - "handlers": [ - { - "refName": "handle-timeout-error" - }, - { - "when": [ - { "status": 503 } - ], - "retry": "my-retry-policy" - } - ] - } - ] - } -} -``` - - | -- -```yaml -errors: - policies: - - name: 'my-retry-policy' - handlers: - - refName: 'handle-timeout-error' - - when: - - status: 503 - retry: 'my-retry-policy' -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "when": [ - { - "status": 503 - } - ], - "then": { - "transition": "my-state" - } -} -``` - - | -- -```yaml -when: - - status: 503 -then: - transition: 'my-state' -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "throw": { - "type": "https://serverlessworkflow.io/spec/errors/runtime", - "status": 400, - "detail": "${ $CONST.localizedErrorDetail }" - } -} -``` - - | -- -```yaml -throw: - type: https://serverlessworkflow.io/spec/errors/runtime - status: 400 - detail: ${ $CONST.localizedErrorDetail } -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "name": "timeout-retry-strat", - "delay": "PT2M", - "maxAttempts": 3, - "jitter": "PT0.001S" -} -``` - - | -- -```yaml -name: timeout-retry-strat -delay: PT2M -maxAttempts: 3 -jitter: PT0.001S -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "produceEvents": [{ - "eventRef": "produce-result-event", - "data": "${ .result.data }" - }], - "nextState": "eval-result-state" -} -``` - - | -- -```yaml -produceEvents: -- eventRef: produce-result-event - data: "${ .result.data }" -nextState: eval-result-state -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "name": "eighteen-or-older", - "condition": "${ .applicant | .age >= 18 }", - "transition": "start-application" -} -``` - - | -- -```yaml -name: eighteen-or-older -condition: "${ .applicant | .age >= 18 }" -transition: start-application -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "name": "visa-approved", - "eventRef": "visa-approved-event", - "transition": "handle-approved-visa" -} -``` - - | -- -```yaml -name: visa-approved -eventRef: visa-approved-event -transition: handle-approved-visa -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "name": "branch-1", - "actions": [ - { - "functionRef": { - "refName": "function-name-one", - "arguments": { - "order": "${ .someParam }" - } - } - }, - { - "functionRef": { - "refName": "function-name-two", - "arguments": { - "order": "${ .someParamTwo }" - } - } - } - ] -} -``` - - | -- -```yaml -name: branch-1 -actions: -- functionRef: - refName: function-name-one - arguments: - order: "${ .someParam }" -- functionRef: - refName: function-name-two - arguments: - order: "${ .someParamTwo }" -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "stateName": "my-starting-state", - "schedule": "2020-03-20T09:00:00Z/PT2H" -} -``` - - | -- -```yaml -stateName: my-starting-state -schedule: 2020-03-20T09:00:00Z/PT2H -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "cron": "0 0/15 * * * ?" -} -``` - - | -- -```yaml -cron: 0 0/15 * * * ? -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "expression": "0 15,30,45 * ? * *", - "validUntil": "2021-11-05T08:15:30-05:00" -} -``` - - | -- -```yaml -expression: 0 15,30,45 * ? * * -validUntil: '2021-11-05T08:15:30-05:00' -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "terminate": true, - "produceEvents": [{ - "eventRef": "provisioning-complete-event", - "data": "${ .provisionedOrders }" - }] -} -``` - - | -- -```yaml -terminate: true -produceEvents: -- eventRef: provisioning-complete-event - data: "${ .provisionedOrders }" - -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "eventRef": "provisioning-complete-event", - "data": "${ .provisionedOrders }", - "contextAttributes": { - "buyerId": "${ .buyerId }" - } - } -``` - - | -- -```yaml -eventRef: provisioning-complete-event -data: "${ .provisionedOrders }" -contextAttributes: - buyerId: "${ .buyerId }" -``` - - | -
JSON | -YAML | -
---|---|
- -```json -{ - "actions": [ - { - "name": "my-action", - "functionRef": "my-function", - "onErrors": [ - { - "when": [ - { - "status": 503 - } - ], - "retry": "retry-five-times" - } - ] - } - ] -} - -``` - - | -- -```yaml -actions: - - name: my-action - functionRef: my-function - onErrors: - - when: - - status: 503 - retry: retry-five-times -``` - - | -
JSON | -YAML | -
---|---|
- -```json -{ - "errors": { - "definitions": [ - { - "name": "service-not-available-error", - "type": "https://serverlessworkflow.io/spec/errors/communication", - "status": 503, - "title": "Service Not Available", - "detail": "Failed to contact service, even after multiple retries" - } - ], - "handlers": [ - { - "name": "handle-503", - "when": [ - { - "status": 503 - } - ], - "retry": "retry-five-times", - "then": { - "throw": { - "refName": "service-not-available-error" - } - } - } - ] - }, - "states": [ - { - "name": "my-state", - "type": "operation", - "actions": [ - { - "name": "my-action", - "functionRef": "my-function", - "onErrors": [ - { - "refName": "handle-503" - } - ] - } - ] - } - ] -} - -``` - - | -- -```yaml -errors: - definitions: - - name: service-not-available-error - type: https://serverlessworkflow.io/spec/errors/communication - status: 503 - title: Service Not Available - detail: Failed to contact service, even after multiple retries - handlers: - - name: handle-503 - when: - - status: 503 - retry: retry-five-times - then: - throw: - refName: service-not-available-error -states: - - name: my-state - type: operation - actions: - - name: my-action - functionRef: my-function - onErrors: - - refName: handle-503 -``` - - | -
JSON | -YAML | -
---|---|
- -```json -{ - "errors": { - "definitions": [ - { - "name": "service-not-available-error", - "type": "https://serverlessworkflow.io/spec/errors/communication", - "status": 503, - "title": "Service Not Available", - "detail": "Failed to contact service, even after multiple retries" - } - ], - "handlers": [ - { - "name": "handle-503", - "when": [ - { - "status": 503 - } - ], - "retry": "retry-five-times", - "then": { - "throw": { - "refName": "service-not-available-error" - } - } - } - ] - }, - "states": [ - { - "name": "my-state", - "type": "operation", - "actions": [ - { - "name": "my-action", - "functionRef": "my-function", - "onErrors": [ - { - "refName": "handle-503" - } - ] - } - ] - } - ] -} - -``` - - | -- -```yaml -errors: - definitions: - - name: service-not-available-error - type: https://serverlessworkflow.io/spec/errors/communication - status: 503 - title: Service Not Available - detail: Failed to contact service, even after multiple retries - handlers: - - name: handle-503 - when: - - status: 503 - retry: retry-five-times - then: - throw: - refName: service-not-available-error - policy: - - name: fault-tolerance - handlers: - - refName: handle-503 -states: - - name: my-state - type: operation - actions: - - name: my-action - functionRef: my-function - onErrors: fault-tolerance -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "duration": "PT2M", - "runBefore": "createandsendreport" -} -``` - - | -- -```yaml -duration: PT2M -runBefore: createandsendreport -``` - - | -
JSON | -YAML | -
---|---|
- -```json - { - "states": [ - { - "name": "new-item-purchase", - "type": "event", - "onEvents": [ - { - "eventRefs": [ - "new-purchase" - ], - "actions": [ - { - "functionRef": { - "refName": "debit-customer-function", - "arguments": { - "customerid": "${ .purchase.customerid }", - "amount": "${ .purchase.amount }" - } - } - }, - { - "functionRef": { - "refName": "send-purchase-confirmation-email-function", - "arguments": { - "customerid": "${ .purchase.customerid }" - } - } - } - ] - } - ], - "compensatedBy": "cancel-purchase", - "transition": "some-next-workflow-state" - }, - { - "name": "cancel-purchase", - "type": "operation", - "usedForCompensation": true, - "actions": [ - { - "functionRef": { - "refName": "credit-customer-function", - "arguments": { - "customerid": "${ .purchase.customerid }", - "amount": "${ .purchase.amount }" - } - } - }, - { - "functionRef": { - "refName": "send-purchase-cancellation-email-function", - "arguments": { - "customerid": "${ .purchase.customerid }" - } - } - } - ] - } - ] - } -``` - - | -- -```yaml -states: -- name: new-item-purchase - type: event - onEvents: - - eventRefs: - - new-purchase - actions: - - functionRef: - refName: debit-customer-function - arguments: - customerid: "${ .purchase.customerid }" - amount: "${ .purchase.amount }" - - functionRef: - refName: send-purchase-confirmation-email-function - arguments: - customerid: "${ .purchase.customerid }" - compensatedBy: cancel-purchase - transition: some-next-workflow-state -- name: CancelPurchase - type: operation - usedForCompensation: true - actions: - - functionRef: - refName: credit-customer-function - arguments: - customerid: "${ .purchase.customerid }" - amount: "${ .purchase.amount }" - - functionRef: - refName: send-purchase-cancellation-email-function - arguments: - customerid: "${ .purchase.customerid }" -``` - - | -
JSON | -YAML | -
---|---|
- -```json -{ - "transition": { - "compensate": true, - "nextState": "next-workflow-state" - } -} -``` - - | -- -```yaml -transition: - compensate: true - nextState: next-workflow-state -``` - - | -
JSON | -YAML | -
---|---|
- -```json -{ - "end": { - "compensate": true - } -} -``` - - | -- -```yaml -end: - compensate: true -``` - - | -
-
-
-
-
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: